Merge "Merge remote-tracking branch 'origin/dev' into 5.11" into refs/staging/5.11

bb10
Jani Heikkinen 2018-02-10 20:39:02 +00:00 committed by The Qt Project
commit 095dbc494c
5332 changed files with 4551 additions and 1014 deletions

View File

@ -119,6 +119,11 @@ Build options:
-testcocoon .......... Instrument with the TestCocoon code coverage tool [no]
-gcov ................ Instrument with the GCov code coverage tool [no]
-trace [backend] ..... Enable instrumentation with tracepoints.
Currently supported backends are 'etw' (Windows) and
'lttng' (Linux), or 'yes' for auto-detection. [no]
-sanitize {address|thread|memory|undefined}
Instrument with the specified compiler sanitizer.

View File

@ -3,7 +3,7 @@ CONFIG += no_docs_target
SUBDIRS = \
ipc \
json \
mimetypes \
serialization \
threads \
tools

View File

@ -8,7 +8,7 @@ CONFIG -= app_bundle
TEMPLATE = app
# install
target.path = $$[QT_INSTALL_EXAMPLES]/corelib/json/savegame
target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/savegame
INSTALLS += target
SOURCES += main.cpp \

View File

@ -38,5 +38,5 @@ defineTest(addExclusiveBuilds) {
}
# Default directories to process
QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR
QMAKE_DIR_REPLACE_SANE += QGLTF_DIR
QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR
QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR

View File

@ -25,6 +25,7 @@ OBJECTS_DIR = .obj
MOC_DIR = .moc
RCC_DIR = .rcc
UI_DIR = .uic
TRACEGEN_DIR = .tracegen
intel_icl {
# ICL 14.0 has a bug that makes it not find #includes in dirs starting with .
MOC_DIR = tmp/moc

View File

@ -0,0 +1,54 @@
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
qtPrepareTool(QMAKE_TRACEGEN, tracegen)
isEmpty(TRACEGEN_DIR): TRACEGEN_DIR = .
PROVIDER_NAME = qt$$lower($$MODULE)
INCLUDEPATH += $$absolute_path($$TRACEGEN_DIR, $$OUT_PWD)
HEADER_PATH = $$OUT_PWD/$$TRACEGEN_DIR/$${PROVIDER_NAME}_tracepoints_p$${first(QMAKE_EXT_H)}
!force_bootstrap:if(qtConfig(lttng)|qtConfig(etw)) {
SOURCE_PATH = $$OUT_PWD/$$TRACEGEN_DIR/$${PROVIDER_NAME}_tracepoints$${first(QMAKE_EXT_CPP)}
isEmpty(BUILDS)|build_pass {
impl_file_contents = \
"$${LITERAL_HASH}define TRACEPOINT_CREATE_PROBES" \
"$${LITERAL_HASH}define TRACEPOINT_DEFINE" \
"$${LITERAL_HASH}include \"$${HEADER_PATH}\""
write_file($$SOURCE_PATH, impl_file_contents)|error()
}
GENERATED_SOURCES += $$SOURCE_PATH
tracegen.input = TRACEPOINT_PROVIDER
tracegen.output = $$HEADER_PATH
tracegen.variable_out = HEADERS
tracegen.depends += $$QMAKE_TRACEGEN_EXE
tracegen.CONFIG = target_predeps
qtConfig(lttng) {
tracegen.commands = $$QMAKE_TRACEGEN lttng ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
QMAKE_USE_PRIVATE += lttng-ust
} else {
tracegen.commands = $$QMAKE_TRACEGEN etw ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
}
QMAKE_EXTRA_COMPILERS += tracegen
DEFINES += Q_TRACEPOINT
} else {
isEmpty(BUILDS)|build_pass {
header_file_contents = "$${LITERAL_HASH}include <private/qtrace_p.h>"
write_file($$HEADER_PATH, header_file_contents)|error()
}
}

View File

@ -77,7 +77,6 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/global/qrandom.cpp \
$(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp \
$(SOURCE_PATH)/src/corelib/io/qbuffer.cpp \
$(SOURCE_PATH)/src/corelib/io/qdatastream.cpp \
$(SOURCE_PATH)/src/corelib/io/qdebug.cpp \
$(SOURCE_PATH)/src/corelib/io/qdir.cpp \
$(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp \
@ -91,18 +90,21 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \
$(SOURCE_PATH)/src/corelib/io/qsettings.cpp \
$(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp \
$(SOURCE_PATH)/src/corelib/io/qtextstream.cpp \
$(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp \
$(SOURCE_PATH)/src/corelib/json/qjson.cpp \
$(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp \
$(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp \
$(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp \
$(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp \
$(SOURCE_PATH)/src/corelib/kernel/qcore_mac_objc.mm \
$(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp \
$(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp \
$(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp \
$(SOURCE_PATH)/src/corelib/plugin/quuid.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qdatastream.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjsonarray.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjson.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjsondocument.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjsonobject.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjsonparser.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qjsonvalue.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qtextstream.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qxmlstream.cpp \
$(SOURCE_PATH)/src/corelib/serialization/qxmlutils.cpp \
$(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp \
$(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp \
$(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp\
@ -123,8 +125,6 @@ DEPEND_SRC = \
$(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp \
$(SOURCE_PATH)/src/corelib/tools/qversionnumber.cpp \
$(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp \
$(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp \
$(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp \
$(QTSRCS) $(QTSRCS2)
# QTSRCS and QTSRCS2 come from Makefile.unix.* (concatenated with this
# by configure); QTSRCS2 may include *.mm entries on macOS.
@ -256,9 +256,6 @@ projectgenerator.o: $(QMKSRC)/generators/projectgenerator.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qtextstream.o: $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qvariant.o: $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
@ -367,9 +364,6 @@ qlocale_win.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
qversionnumber.o: $(SOURCE_PATH)/src/corelib/tools/qversionnumber.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qdatastream.o: $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qbuffer.o: $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
@ -454,34 +448,40 @@ qlinkedlist.o: $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjson.o: $(SOURCE_PATH)/src/corelib/json/qjson.cpp
qdatastream.o: $(SOURCE_PATH)/src/corelib/serialization/qdatastream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjsondocument.o: $(SOURCE_PATH)/src/corelib/json/qjsondocument.cpp
qjson.o: $(SOURCE_PATH)/src/corelib/serialization/qjson.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjsonparser.o: $(SOURCE_PATH)/src/corelib/json/qjsonparser.cpp
qjsondocument.o: $(SOURCE_PATH)/src/corelib/serialization/qjsondocument.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjsonarray.o: $(SOURCE_PATH)/src/corelib/json/qjsonarray.cpp
qjsonparser.o: $(SOURCE_PATH)/src/corelib/serialization/qjsonparser.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjsonobject.o: $(SOURCE_PATH)/src/corelib/json/qjsonobject.cpp
qjsonarray.o: $(SOURCE_PATH)/src/corelib/serialization/qjsonarray.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjsonvalue.o: $(SOURCE_PATH)/src/corelib/json/qjsonvalue.cpp
qjsonobject.o: $(SOURCE_PATH)/src/corelib/serialization/qjsonobject.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qjsonvalue.o: $(SOURCE_PATH)/src/corelib/serialization/qjsonvalue.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qxmlstream.o: $(SOURCE_PATH)/src/corelib/serialization/qxmlstream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qxmlutils.o: $(SOURCE_PATH)/src/corelib/serialization/qxmlutils.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
qtextstream.o: $(SOURCE_PATH)/src/corelib/serialization/qtextstream.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $<
# DO NOT DELETE THIS LINE -- make depend depends on it

View File

@ -197,15 +197,12 @@ qmake_pch.obj:
{$(SOURCE_PATH)\src\corelib\plugin}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
{$(SOURCE_PATH)\src\corelib\serialization}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
{$(SOURCE_PATH)\src\corelib\tools}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
{$(SOURCE_PATH)\src\corelib\xml}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
{$(SOURCE_PATH)\src\corelib\json}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
# Make sure qstring_compat.obj and qlibraryinfo.obj aren't compiled with PCH enabled
qstring_compat.obj: $(SOURCE_PATH)\src\corelib\tools\qstring_compat.cpp
$(CXX) -c $(CXXFLAGS_BARE) $(SOURCE_PATH)\src\corelib\tools\qstring_compat.cpp

View File

@ -16,9 +16,8 @@ VPATH += \
../src/corelib/kernel \
../src/corelib/codecs \
../src/corelib/plugin \
../src/corelib/xml \
../src/corelib/io \
../src/corelib/json \
../src/corelib/serialization \
../tools/shared/windows
INCLUDEPATH += . \

View File

@ -15,7 +15,8 @@
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
"slog2": "boolean",
"syslog": "boolean"
"syslog": "boolean",
"trace": { "type": "optionalString", "values": [ "etw", "lttng", "no", "yes" ] }
}
},
@ -147,6 +148,18 @@
"-lrt"
]
},
"lttng-ust": {
"label": "lttng-ust",
"test": {
"include": "lttng/ust-events.h",
"main": "lttng_session_destroy(nullptr);"
},
"sources": [
{ "type": "pkgConfig", "args": "lttng-ust" },
"-llttng-ust"
],
"use": "libdl"
},
"pcre2": {
"label": "PCRE2",
"test": {
@ -858,6 +871,22 @@
"section": "Utilities",
"output": [ "publicFeature" ]
},
"lttng": {
"label": "LTTNG",
"autoDetect": false,
"enable": "input.trace == 'lttng' || (input.trace =='yes' && config.linux)",
"disable": "input.trace == 'etw' || input.trace =='no'",
"condition": "config.linux && libs.lttng-ust",
"output": [ "privateFeature" ]
},
"etw": {
"label": "ETW",
"autoDetect": false,
"enable": "input.trace == 'etw' || (input.trace == 'yes' && config.win32)",
"disable": "input.trace == 'lttng' || input.trace == 'no'",
"condition": "config.win32",
"output": [ "privateFeature" ]
},
"topleveldomain": {
"label": "QUrl::topLevelDomain()",
"purpose": "Provides support for extracting the top level domain from URLs.
@ -907,6 +936,11 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"glib",
"iconv",
"icu",
{
"message": "Tracing backend",
"type": "firstAvailableFeature",
"args": "etw lttng"
},
{
"section": "Logging backends",
"entries": [

View File

@ -6,6 +6,9 @@ MODULE = core # not corelib, as per project file
MODULE_CONFIG = moc resources
!isEmpty(QT_NAMESPACE): MODULE_DEFINES = QT_NAMESPACE=$$QT_NAMESPACE
TRACEPOINT_PROVIDER = $$PWD/qtcore.tracepoints
CONFIG += qt_tracepoints
CONFIG += $$MODULE_CONFIG
DEFINES += $$MODULE_DEFINES
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
@ -35,13 +38,12 @@ include(thread/thread.pri)
include(tools/tools.pri)
include(io/io.pri)
include(itemmodels/itemmodels.pri)
include(json/json.pri)
include(plugin/plugin.pri)
include(kernel/kernel.pri)
include(codecs/codecs.pri)
include(serialization/serialization.pri)
include(statemachine/statemachine.pri)
include(mimetypes/mimetypes.pri)
include(xml/xml.pri)
win32 {
LIBS_PRIVATE += -lws2_32

View File

@ -78,6 +78,7 @@
#define QT_FEATURE_cxx11_random (QT_HAS_INCLUDE(<random>) ? 1 : -1)
#define QT_NO_DATASTREAM
#define QT_FEATURE_datetimeparser -1
#define QT_FEATURE_etw -1
#define QT_FEATURE_getauxval (QT_HAS_INCLUDE(<sys/auxv.h>) ? 1 : -1)
#define QT_FEATURE_getentropy -1
#define QT_NO_GEOM_VARIANT
@ -92,6 +93,7 @@
#else
# define QT_FEATURE_linkat -1
#endif
#define QT_FEATURE_lttng -1
#define QT_NO_QOBJECT
#define QT_FEATURE_process -1
#define QT_FEATURE_regularexpression -1

View File

@ -178,6 +178,7 @@ static void qFloatFromFloat16_fast(float *, const quint16 *, qsizetype) Q_DECL_N
#endif
/*!
\since 5.11
\relates <QFloat16>
Converts \a len floats from \a in to qfloat16 and stores them in \a out.
Both \a in and \a out must have \a len allocated entries.
@ -193,6 +194,7 @@ Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *out, const float *in, qsizetype len
/*!
\since 5.11
\relates <QFloat16>
Converts \a len qfloat16 from \a in to floats and stores them in \a out.
Both \a in and \a out must have \a len allocated entries.

View File

@ -88,6 +88,11 @@
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
# define QT_NO_UNSHARABLE_CONTAINERS
# define QT6_VIRTUAL virtual
# define QT6_NOT_VIRTUAL
#else
# define QT6_VIRTUAL
# define QT6_NOT_VIRTUAL virtual
#endif
/* These two macros makes it possible to turn the builtin line expander into a

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -58,8 +58,6 @@
#if defined(Q_CC_MSVC)
# include <intrin.h>
#elif defined(Q_CC_INTEL)
# include <immintrin.h> // for _addcarry_u<nn>
#endif
#if defined(Q_CC_MSVC)
@ -164,10 +162,33 @@ Q_DECL_CONST_FUNCTION static inline bool qt_is_finite(float f)
}
#ifndef Q_CLANG_QDOC
//
// Unsigned overflow math
//
namespace {
// Overflow math.
// This provides efficient implementations for int, unsigned, qsizetype and
// size_t. Implementations for 8- and 16-bit types will work but may not be as
// efficient. Implementations for 64-bit may be missing on 32-bit platforms.
#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || defined(Q_CC_INTEL)) || QT_HAS_BUILTIN(__builtin_add_overflowx)
// GCC 5, ICC 18, and Clang 3.8 have builtins to detect overflows
template <typename T> inline
typename std::enable_if<std::is_unsigned<T>::value || std::is_signed<T>::value, bool>::type
add_overflow(T v1, T v2, T *r)
{ return __builtin_add_overflow(v1, v2, r); }
template <typename T> inline
typename std::enable_if<std::is_unsigned<T>::value || std::is_signed<T>::value, bool>::type
sub_overflow(T v1, T v2, T *r)
{ return __builtin_sub_overflow(v1, v2, r); }
template <typename T> inline
typename std::enable_if<std::is_unsigned<T>::value || std::is_signed<T>::value, bool>::type
mul_overflow(T v1, T v2, T *r)
{ return __builtin_mul_overflow(v1, v2, r); }
#else
// Generic implementations
template <typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type
add_overflow(T v1, T v2, T *r)
{
@ -176,69 +197,92 @@ add_overflow(T v1, T v2, T *r)
return v1 > T(v1 + v2);
}
template <typename T> inline typename std::enable_if<std::is_signed<T>::value, bool>::type
add_overflow(T v1, T v2, T *r)
{
// Here's how we calculate the overflow:
// 1) unsigned addition is well-defined, so we can always execute it
// 2) conversion from unsigned back to signed is implementation-
// defined and in the implementations we use, it's a no-op.
// 3) signed integer overflow happens if the sign of the two input operands
// is the same but the sign of the result is different. In other words,
// the sign of the result must be the same as the sign of either
// operand.
using U = typename std::make_unsigned<T>::type;
*r = T(U(v1) + U(v2));
// If int is two's complement, assume all integer types are too.
if (std::is_same<int32_t, int>::value) {
// Two's complement equivalent (generates slightly shorter code):
// x ^ y is negative if x and y have different signs
// x & y is negative if x and y are negative
// (x ^ z) & (y ^ z) is negative if x and z have different signs
// AND y and z have different signs
return ((v1 ^ *r) & (v2 ^ *r)) < 0;
}
bool s1 = (v1 < 0);
bool s2 = (v2 < 0);
bool sr = (*r < 0);
return s1 != sr && s2 != sr;
// also: return s1 == s2 && s1 != sr;
}
template <typename T> inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type
sub_overflow(T v1, T v2, T *r)
{
// unsigned subtractions are well-defined
*r = v1 - v2;
return v1 < v2;
}
template <typename T> inline typename std::enable_if<std::is_signed<T>::value, bool>::type
sub_overflow(T v1, T v2, T *r)
{
// See above for explanation. This is the same with some signs reversed.
// We can't use add_overflow(v1, -v2, r) because it would be UB if
// v2 == std::numeric_limits<T>::min().
using U = typename std::make_unsigned<T>::type;
*r = T(U(v1) - U(v2));
if (std::is_same<int32_t, int>::value)
return ((v1 ^ *r) & (~v2 ^ *r)) < 0;
bool s1 = (v1 < 0);
bool s2 = !(v2 < 0);
bool sr = (*r < 0);
return s1 != sr && s2 != sr;
// also: return s1 == s2 && s1 != sr;
}
template <typename T> inline
typename std::enable_if<std::is_unsigned<T>::value || std::is_signed<T>::value, bool>::type
mul_overflow(T v1, T v2, T *r)
{
// use the next biggest type
// Note: for 64-bit systems where __int128 isn't supported, this will cause an error.
// A fallback is present below.
typedef typename QIntegerForSize<sizeof(T) * 2>::Unsigned Larger;
using LargerInt = QIntegerForSize<sizeof(T) * 2>;
using Larger = typename std::conditional<std::is_signed<T>::value,
typename LargerInt::Signed, typename LargerInt::Unsigned>::type;
Larger lr = Larger(v1) * Larger(v2);
*r = T(lr);
return lr > std::numeric_limits<T>::max();
return lr > std::numeric_limits<T>::max() || lr < std::numeric_limits<T>::min();
}
#if defined(__SIZEOF_INT128__)
# define HAVE_MUL64_OVERFLOW
#endif
// GCC 5 and Clang have builtins to detect overflows
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_uadd_overflow)
template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r)
{ return __builtin_uadd_overflow(v1, v2, r); }
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_uaddl_overflow)
template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return __builtin_uaddl_overflow(v1, v2, r); }
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_uaddll_overflow)
template <> inline bool add_overflow(unsigned long long v1, unsigned long long v2, unsigned long long *r)
{ return __builtin_uaddll_overflow(v1, v2, r); }
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_umul_overflow)
template <> inline bool mul_overflow(unsigned v1, unsigned v2, unsigned *r)
{ return __builtin_umul_overflow(v1, v2, r); }
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_umull_overflow)
template <> inline bool mul_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return __builtin_umull_overflow(v1, v2, r); }
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_umulll_overflow)
template <> inline bool mul_overflow(unsigned long long v1, unsigned long long v2, unsigned long long *r)
{ return __builtin_umulll_overflow(v1, v2, r); }
# define HAVE_MUL64_OVERFLOW
#endif
#if (defined(Q_CC_MSVC) || defined(Q_CC_INTEL)) && defined(Q_PROCESSOR_X86) && !QT_HAS_BUILTIN(__builtin_uadd_overflow)
# if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86)
// We can use intrinsics for the unsigned operations with MSVC
template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r)
{ return _addcarry_u32(0, v1, v2, r); }
# ifdef Q_CC_MSVC // longs are 32-bit
template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return _addcarry_u32(0, v1, v2, reinterpret_cast<unsigned *>(r)); }
# endif
#endif
#if (defined(Q_CC_MSVC) || defined(Q_CC_INTEL)) && defined(Q_PROCESSOR_X86_64) && !QT_HAS_BUILTIN(__builtin_uadd_overflow)
// 32-bit mul_overflow is fine with the generic code above
# if defined(Q_PROCESSOR_X86_64)
template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r)
{ return _addcarry_u64(0, v1, v2, reinterpret_cast<unsigned __int64 *>(r)); }
# ifndef Q_CC_MSVC // longs are 64-bit
template <> inline bool add_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{ return _addcarry_u64(0, v1, v2, reinterpret_cast<unsigned __int64 *>(r)); }
# endif
#endif
#if defined(Q_CC_MSVC) && (defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_IA64)) && !QT_HAS_BUILTIN(__builtin_uadd_overflow)
#pragma intrinsic(_umul128)
# pragma intrinsic(_umul128)
template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
{
// use 128-bit multiplication with the _umul128 intrinsic
@ -247,117 +291,30 @@ template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
*r = _umul128(v1, v2, &high);
return high;
}
# define HAVE_MUL64_OVERFLOW
#endif
#if !defined(HAVE_MUL64_OVERFLOW) && defined(__LP64__)
// no 128-bit multiplication, we need to figure out with a slow division
template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r)
# pragma intrinsic(_mul128)
template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r)
{
if (v2 && v1 > std::numeric_limits<quint64>::max() / v2)
return true;
*r = v1 * v2;
return false;
}
template <> inline bool mul_overflow(unsigned long v1, unsigned long v2, unsigned long *r)
{
return mul_overflow<quint64>(v1, v2, reinterpret_cast<quint64 *>(r));
}
#else
# undef HAVE_MUL64_OVERFLOW
#endif
// Use 128-bit multiplication with the _mul128 intrinsic
// https://msdn.microsoft.com/en-us/library/82cxdw50.aspx
//
// Signed overflow math
//
// In C++, signed overflow math is Undefined Behavior. However, many CPUs do implement some way to
// check for overflow. Some compilers expose intrinsics to use this functionality. If the no
// intrinsic is exposed, overflow checking can be done by widening the result type and "manually"
// checking for overflow. Or, alternatively, by using inline assembly to use the CPU features.
//
// Only int overflow checking is implemented, because it's the only one used.
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_sadd_overflow)
inline bool add_overflow(int v1, int v2, int *r)
{ return __builtin_sadd_overflow(v1, v2, r); }
#elif defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
inline bool add_overflow(int v1, int v2, int *r)
{
quint8 overflow = 0;
int res = v1;
// This is slightly more complex than the unsigned case above: the sign bit
// of 'low' must be replicated as the entire 'high', so the only valid
// values for 'high' are 0 and -1.
asm ("addl %2, %1\n"
"seto %0"
: "=q" (overflow), "=r" (res)
: "r" (v2), "1" (res)
: "cc"
);
*r = res;
return overflow;
qint64 high;
*r = _mul128(v1, v2, &high);
if (high == 0)
return *r < 0;
if (high == -1)
return *r >= 0;
return true;
}
#else
inline bool add_overflow(int v1, int v2, int *r)
{
qint64 t = qint64(v1) + v2;
*r = static_cast<int>(t);
return t > std::numeric_limits<int>::max() || t < std::numeric_limits<int>::min();
# endif // x86-64
# endif // MSVC x86
#endif // !GCC
}
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_ssub_overflow)
inline bool sub_overflow(int v1, int v2, int *r)
{ return __builtin_ssub_overflow(v1, v2, r); }
#elif defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
inline bool sub_overflow(int v1, int v2, int *r)
{
quint8 overflow = 0;
int res = v1;
asm ("subl %2, %1\n"
"seto %0"
: "=q" (overflow), "=r" (res)
: "r" (v2), "1" (res)
: "cc"
);
*r = res;
return overflow;
}
#else
inline bool sub_overflow(int v1, int v2, int *r)
{
qint64 t = qint64(v1) - v2;
*r = static_cast<int>(t);
return t > std::numeric_limits<int>::max() || t < std::numeric_limits<int>::min();
}
#endif
#if (defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 500) || QT_HAS_BUILTIN(__builtin_smul_overflow)
inline bool mul_overflow(int v1, int v2, int *r)
{ return __builtin_smul_overflow(v1, v2, r); }
#elif defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86)
inline bool mul_overflow(int v1, int v2, int *r)
{
quint8 overflow = 0;
int res = v1;
asm ("imul %2, %1\n"
"seto %0"
: "=q" (overflow), "=r" (res)
: "r" (v2), "1" (res)
: "cc"
);
*r = res;
return overflow;
}
#else
inline bool mul_overflow(int v1, int v2, int *r)
{
qint64 t = qint64(v1) * v2;
*r = static_cast<int>(t);
return t > std::numeric_limits<int>::max() || t < std::numeric_limits<int>::min();
}
#endif
#endif // Q_CLANG_QDOC
}
QT_END_NAMESPACE

View File

@ -0,0 +1,126 @@
/****************************************************************************
**
** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.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 QTRACE_P_H
#define QTRACE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
/*
* The Qt tracepoints API consists of only three macros:
*
* - Q_TRACE(tracepoint, args...)
* Fires 'tracepoint' if it is enabled.
*
* - Q_UNCONDITIONAL_TRACE(tracepoint, args...)
* Fires 'tracepoint' unconditionally: no check is performed to query
* whether 'tracepoint' is enabled.
*
* - Q_TRACE_ENABLED(tracepoint)
* Returns 'true' if 'tracepoint' is enabled; false otherwise.
*
* When using LTTNG, Q_TRACE, Q_UNCONDITIONAL_TRACE and Q_TRACE_ENABLED map
* ultimately to tracepoint(), do_tracepoint() and tracepoint_enabled(),
* respectively, described on the lttng-ust manpage (man 3 lttng-ust).
*
* On ETW, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, ultimately
* amounting to a call to TraceLoggingWrite(), whereas Q_TRACE_ENABLED()
* wraps around TraceLoggingProviderEnabled().
*
* A tracepoint provider is defined in a separate file, that follows the
* following format:
*
* tracepoint_name(arg_type arg_name, ...)
*
* For instance:
*
* qcoreapplication_ctor(int argc, const char * const argv)
* qcoreapplication_foo(int argc, const char[10] argv)
* qcoreapplication_baz(const char[len] some_string, unsigned int len)
* qcoreapplication_qstring(const QString &foo)
* qcoreapplication_qrect(const QRect &rect)
*
* The provider file is then parsed by src/tools/tracegen, which can be
* switched to output either ETW or LTTNG tracepoint definitions. The provider
* name is deduced to be basename(provider_file).
*
* To use the above (inside qtcore), you need to include
* <providername_tracepoints_p.h>. After that, the following call becomes
* possible:
*
* Q_TRACE(qcoreapplication_qrect, myRect);
*
* Currently, all C++ primitive non-pointer types are supported for
* arguments. Additionally, char * is supported, and is assumed to
* be a NULL-terminated string. Finally, the following subset of Qt types also
* currently supported:
*
* - QString
* - QByteArray
* - QUrl
* - QRect
*
* Dynamic arrays are supported using the syntax illustrated by
* qcoreapplication_baz above.
*/
QT_BEGIN_NAMESPACE
#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
# define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
# define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
# define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
#else
# define Q_TRACE(x, ...)
# define Q_UNCONDITIONAL_TRACE(x, ...)
# define Q_TRACE_ENABLED(x) false
#endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
QT_END_NAMESPACE
#endif // QTRACE_P_H

View File

@ -3,8 +3,6 @@
HEADERS += \
io/qabstractfileengine_p.h \
io/qbuffer.h \
io/qdatastream.h \
io/qdatastream_p.h \
io/qdataurl_p.h \
io/qdebug.h \
io/qdebug_p.h \
@ -22,8 +20,6 @@ HEADERS += \
io/qlockfile.h \
io/qlockfile_p.h \
io/qnoncontiguousbytedevice_p.h \
io/qtextstream.h \
io/qtextstream_p.h \
io/qtemporarydir.h \
io/qtemporaryfile.h \
io/qtemporaryfile_p.h \
@ -57,7 +53,6 @@ HEADERS += \
SOURCES += \
io/qabstractfileengine.cpp \
io/qbuffer.cpp \
io/qdatastream.cpp \
io/qdataurl.cpp \
io/qtldurl.cpp \
io/qdebug.cpp \
@ -71,7 +66,6 @@ SOURCES += \
io/qlockfile.cpp \
io/qnoncontiguousbytedevice.cpp \
io/qstorageinfo.cpp \
io/qtextstream.cpp \
io/qtemporarydir.cpp \
io/qtemporaryfile.cpp \
io/qresource.cpp \

View File

@ -1,17 +0,0 @@
HEADERS += \
json/qjson_p.h \
json/qjsondocument.h \
json/qjsonobject.h \
json/qjsonvalue.h \
json/qjsonarray.h \
json/qjsonwriter_p.h \
json/qjsonparser_p.h
SOURCES += \
json/qjson.cpp \
json/qjsondocument.cpp \
json/qjsonobject.cpp \
json/qjsonarray.cpp \
json/qjsonvalue.cpp \
json/qjsonwriter.cpp \
json/qjsonparser.cpp

View File

@ -116,6 +116,12 @@
# include <taskLib.h>
#endif
#ifdef QT_BOOTSTRAPPED
#include <private/qtrace_p.h>
#else
#include <qtcore_tracepoints_p.h>
#endif
#include <algorithm>
QT_BEGIN_NAMESPACE
@ -790,6 +796,8 @@ QCoreApplication::QCoreApplication(int &argc, char **argv
void QCoreApplicationPrivate::init()
{
Q_TRACE(qcoreapplicationprivate_init_entry);
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
#endif
@ -873,6 +881,8 @@ void QCoreApplicationPrivate::init()
#ifndef QT_NO_QOBJECT
is_app_running = true; // No longer starting up.
#endif
Q_TRACE(qcoreapplicationprivate_init_exit);
}
/*!

View File

@ -112,14 +112,15 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
if (CFStringRef mode = runLoopMode(notification.userInfo))
m_runLoopModes.push(mode);
else
qWarning("Encountered run loop push notification without run loop mode!");
qCWarning(lcEventDispatcher) << "Encountered run loop push notification without run loop mode!";
} else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) {
CFStringRef mode = runLoopMode(notification.userInfo);
if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo)
m_runLoopModes.pop();
else
qWarning("Tried to pop run loop mode '%s' that was never pushed!", qPrintable(QString::fromCFString(mode)));
qCWarning(lcEventDispatcher) << "Tried to pop run loop mode"
<< qPrintable(QString::fromCFString(mode)) << "that was never pushed!";
Q_ASSERT(m_runLoopModes.size() >= 1);
}
@ -134,6 +135,9 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher");
Q_LOGGING_CATEGORY(lcEventDispatcherTimers, "qt.eventdispatcher.timers");
class RunLoopDebugger : public QObject
{
Q_OBJECT
@ -177,10 +181,6 @@ QDebug operator<<(QDebug s, timespec tv)
return s;
}
#if DEBUG_EVENT_DISPATCHER
uint g_eventDispatcherIndentationLevel = 0;
#endif
static const CFTimeInterval kCFTimeIntervalMinimum = 0;
static const CFTimeInterval kCFTimeIntervalDistantFuture = std::numeric_limits<CFTimeInterval>::max();
@ -190,13 +190,7 @@ QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent)
: QAbstractEventDispatcher(parent)
, m_processEvents(QEventLoop::EventLoopExec)
, m_postedEventsRunLoopSource(this, &QEventDispatcherCoreFoundation::processPostedEvents)
, m_runLoopActivityObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity,
#if DEBUG_EVENT_DISPATCHER
kCFRunLoopAllActivities
#else
kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting
#endif
)
, m_runLoopActivityObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity, kCFRunLoopAllActivities)
, m_runLoopModeTracker([[RunLoopModeTracker alloc] init])
, m_runLoopTimer(0)
, m_blockedRunLoopTimer(0)
@ -247,14 +241,14 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
bool eventsProcessed = false;
if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers))
qWarning() << "processEvents() flags" << flags << "not supported on iOS";
qCWarning(lcEventDispatcher) << "processEvents() flags" << flags << "not supported on iOS";
qEventDispatcherDebug() << "Entering with " << flags; qIndent();
qCDebug(lcEventDispatcher) << "Processing events with flags" << flags;
if (m_blockedRunLoopTimer) {
Q_ASSERT(m_blockedRunLoopTimer == m_runLoopTimer);
qEventDispatcherDebug() << "Recursing from blocked timer " << m_blockedRunLoopTimer;
qCDebug(lcEventDispatcher) << "Recursing from blocked timer" << m_blockedRunLoopTimer;
m_runLoopTimer = 0; // Unset current timer to force creation of new timer
updateTimers();
}
@ -266,7 +260,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
m_postedEventsRunLoopSource.signal();
m_processEvents.deferredWakeUp = false;
qEventDispatcherDebug() << "Processed deferred wake-up";
qCDebug(lcEventDispatcher) << "Processed deferred wake-up";
}
// The documentation states that this signal is emitted after the event
@ -287,12 +281,12 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
CFTimeInterval duration = (m_processEvents.flags & QEventLoop::WaitForMoreEvents) ?
kCFTimeIntervalDistantFuture : kCFTimeIntervalMinimum;
qEventDispatcherDebug() << "Calling CFRunLoopRunInMode = " << qPrintable(QString::fromCFString(mode))
<< " for " << duration << " ms, processing single source = " << returnAfterSingleSourceHandled; qIndent();
qCDebug(lcEventDispatcher) << "Calling CFRunLoopRunInMode =" << qPrintable(QString::fromCFString(mode))
<< "for" << duration << "ms, processing single source =" << returnAfterSingleSourceHandled;
SInt32 result = CFRunLoopRunInMode(mode, duration, returnAfterSingleSourceHandled);
qUnIndent(); qEventDispatcherDebug() << "result = " << qPrintableResult(result);
qCDebug(lcEventDispatcher) << "result =" << qPrintableResult(result);
eventsProcessed |= (result == kCFRunLoopRunHandledSource
|| m_processEvents.processedPostedEvents
@ -316,15 +310,15 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
// immediately, since it has already been exited.
if (!currentEventLoop()->isRunning()) {
qEventDispatcherDebug() << "Top level event loop was exited";
qCDebug(lcEventDispatcher) << "Top level event loop was exited";
break;
} else {
qEventDispatcherDebug() << "Top level event loop still running, making another pass";
qCDebug(lcEventDispatcher) << "Top level event loop still running, making another pass";
}
} else {
// We were called manually, through processEvents(), and should stop processing
// events, even if we didn't finish processing all the queued events.
qEventDispatcherDebug() << "Top level processEvents was interrupted";
qCDebug(lcEventDispatcher) << "Top level processEvents was interrupted";
break;
}
}
@ -353,7 +347,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
// date in the past (overdue) will fire on the next run loop pass. The Qt
// APIs on the other hand document eg. zero-interval timers to always be
// handled after processing all available window-system events.
qEventDispatcherDebug() << "Manually processing timers due to overdue timer";
qCDebug(lcEventDispatcher) << "Manually processing timers due to overdue timer";
processTimers(0);
eventsProcessed = true;
}
@ -372,7 +366,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
if (m_processEvents.deferredWakeUp) {
m_postedEventsRunLoopSource.signal();
qEventDispatcherDebug() << "Processed deferred wake-up";
qCDebug(lcEventDispatcher) << "Processed deferred wake-up";
}
bool wasInterrupted = m_processEvents.wasInterrupted;
@ -385,11 +379,11 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
// others below it (eg, in the case of nested event loops). We need to trigger
// another interrupt so that the parent processEvents call has a chance to check
// if it should continue.
qEventDispatcherDebug() << "Forwarding interrupt in case of nested processEvents";
qCDebug(lcEventDispatcher) << "Forwarding interrupt in case of nested processEvents";
interrupt();
}
qEventDispatcherDebug() << "Returning with eventsProcessed = " << eventsProcessed; qUnIndent();
qCDebug(lcEventDispatcher) << "Returning with eventsProcessed =" << eventsProcessed;
return eventsProcessed;
}
@ -397,15 +391,14 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag
bool QEventDispatcherCoreFoundation::processPostedEvents()
{
if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
qEventDispatcherDebug() << "Already processed events this pass";
qCDebug(lcEventDispatcher) << "Already processed events this pass";
return false;
}
m_processEvents.processedPostedEvents = true;
qEventDispatcherDebug() << "Sending posted events for " << m_processEvents.flags; qIndent();
qCDebug(lcEventDispatcher) << "Sending posted events for" << m_processEvents.flags;
QCoreApplication::sendPostedEvents();
qUnIndent();
return true;
}
@ -413,12 +406,12 @@ bool QEventDispatcherCoreFoundation::processPostedEvents()
void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
{
if (m_processEvents.processedTimers && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
qEventDispatcherDebug() << "Already processed timers this pass";
qCDebug(lcEventDispatcher) << "Already processed timers this pass";
m_processEvents.deferredUpdateTimers = true;
return;
}
qEventDispatcherDebug() << "CFRunLoopTimer " << timer << " fired, activating Qt timers"; qIndent();
qCDebug(lcEventDispatcher) << "CFRunLoopTimer" << timer << "fired, activating Qt timers";
// Activating Qt timers might recurse into processEvents() if a timer-callback
// brings up a new event-loop or tries to processes events manually. Although
@ -436,15 +429,15 @@ void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
m_blockedRunLoopTimer = previouslyBlockedRunLoopTimer;
m_processEvents.processedTimers = true;
qUnIndent();
// Now that the timer source is unblocked we may need to schedule it again
updateTimers();
}
Q_LOGGING_CATEGORY(lcEventDispatcherActivity, "qt.eventdispatcher.activity")
void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity activity)
{
qEventDispatcherDebug() << qPrintableActivity(activity);
qCDebug(lcEventDispatcherActivity) << "Runloop entered activity" << qPrintableActivity(activity);
switch (activity) {
case kCFRunLoopBeforeWaiting:
@ -463,13 +456,11 @@ void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity act
case kCFRunLoopAfterWaiting:
emit awake();
break;
#if DEBUG_EVENT_DISPATCHER
case kCFRunLoopEntry:
case kCFRunLoopBeforeTimers:
case kCFRunLoopBeforeSources:
case kCFRunLoopExit:
break;
#endif
default:
Q_UNREACHABLE();
}
@ -502,19 +493,19 @@ void QEventDispatcherCoreFoundation::wakeUp()
// posted event gets processed on the next processEvents() call, so we flag the
// need to do a deferred wake-up.
m_processEvents.deferredWakeUp = true;
qEventDispatcherDebug() << "Already processed posted events, deferring wakeUp";
qCDebug(lcEventDispatcher) << "Already processed posted events, deferring wakeUp";
return;
}
m_postedEventsRunLoopSource.signal();
CFRunLoopWakeUp(CFRunLoopGetMain());
qEventDispatcherDebug() << "Signaled posted event run-loop source";
qCDebug(lcEventDispatcher) << "Signaled posted event run-loop source";
}
void QEventDispatcherCoreFoundation::interrupt()
{
qEventDispatcherDebug() << "Marking current processEvent as interrupted";
qCDebug(lcEventDispatcher) << "Marking current processEvent as interrupted";
m_processEvents.wasInterrupted = true;
CFRunLoopStop(CFRunLoopGetMain());
}
@ -540,8 +531,8 @@ void QEventDispatcherCoreFoundation::unregisterSocketNotifier(QSocketNotifier *n
void QEventDispatcherCoreFoundation::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
{
qEventDispatcherDebug() << "id = " << timerId << ", interval = " << interval
<< ", type = " << timerType << ", object = " << object;
qCDebug(lcEventDispatcherTimers) << "Registering timer with id =" << timerId << "interval =" << interval
<< "type =" << timerType << "object =" << object;
Q_ASSERT(timerId > 0 && interval >= 0 && object);
Q_ASSERT(object->thread() == thread() && thread() == QThread::currentThread());
@ -557,7 +548,7 @@ bool QEventDispatcherCoreFoundation::unregisterTimer(int timerId)
bool returnValue = m_timerInfoList.unregisterTimer(timerId);
qEventDispatcherDebug() << "id = " << timerId << ", timers left: " << m_timerInfoList.size();
qCDebug(lcEventDispatcherTimers) << "Unegistered timer with id =" << timerId << "Timers left:" << m_timerInfoList.size();
updateTimers();
return returnValue;
@ -569,7 +560,7 @@ bool QEventDispatcherCoreFoundation::unregisterTimers(QObject *object)
bool returnValue = m_timerInfoList.unregisterTimers(object);
qEventDispatcherDebug() << "object = " << object << ", timers left: " << m_timerInfoList.size();
qCDebug(lcEventDispatcherTimers) << "Unegistered timers for object =" << object << "Timers left:" << m_timerInfoList.size();
updateTimers();
return returnValue;
@ -612,16 +603,16 @@ void QEventDispatcherCoreFoundation::updateTimers()
});
CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimer, kCFRunLoopCommonModes);
qEventDispatcherDebug() << "Created new CFRunLoopTimer " << m_runLoopTimer;
qCDebug(lcEventDispatcherTimers) << "Created new CFRunLoopTimer" << m_runLoopTimer;
} else {
CFRunLoopTimerSetNextFireDate(m_runLoopTimer, timeToFire);
qEventDispatcherDebug() << "Re-scheduled CFRunLoopTimer " << m_runLoopTimer;
qCDebug(lcEventDispatcherTimers) << "Re-scheduled CFRunLoopTimer" << m_runLoopTimer;
}
m_overdueTimerScheduled = !timespecToSeconds(tv);
qEventDispatcherDebug() << "Next timeout in " << tv << " seconds";
qCDebug(lcEventDispatcherTimers) << "Next timeout in" << tv << "seconds";
} else {
// No Qt timers are registered, so make sure we're not running any CF timers
@ -637,7 +628,7 @@ void QEventDispatcherCoreFoundation::invalidateTimer()
return;
CFRunLoopTimerInvalidate(m_runLoopTimer);
qEventDispatcherDebug() << "Invalidated CFRunLoopTimer " << m_runLoopTimer;
qCDebug(lcEventDispatcherTimers) << "Invalidated CFRunLoopTimer" << m_runLoopTimer;
CFRelease(m_runLoopTimer);
m_runLoopTimer = 0;

View File

@ -85,19 +85,22 @@
// We mean it.
//
#define DEBUG_EVENT_DISPATCHER 0
#include <QtCore/qabstracteventdispatcher.h>
#include <QtCore/private/qtimerinfo_unix_p.h>
#include <QtCore/private/qcfsocketnotifier_p.h>
#include <QtCore/private/qcore_mac_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qloggingcategory.h>
#include <CoreFoundation/CoreFoundation.h>
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(RunLoopModeTracker));
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcher);
Q_DECLARE_LOGGING_CATEGORY(lcEventDispatcherTimers)
class QEventDispatcherCoreFoundation;
template <class T = QEventDispatcherCoreFoundation>
@ -269,17 +272,4 @@ private:
QT_END_NAMESPACE
#if DEBUG_EVENT_DISPATCHER
extern uint g_eventDispatcherIndentationLevel;
#define qEventDispatcherDebug() qDebug().nospace() \
<< qPrintable(QString(QLatin1String("| ")).repeated(g_eventDispatcherIndentationLevel)) \
<< __FUNCTION__ << "(): "
#define qIndent() ++g_eventDispatcherIndentationLevel
#define qUnIndent() --g_eventDispatcherIndentationLevel
#else
#define qEventDispatcherDebug() QT_NO_QDEBUG_MACRO()
#define qIndent()
#define qUnIndent()
#endif
#endif // QEVENTDISPATCHER_CF_P_H

View File

@ -3892,6 +3892,19 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p)
\sa setValue(), value()
*/
/*! \fn static inline QVariant fromStdVariant(const std::variant<T, Types...> &value)
\since 5.11
Returns a QVariant with the type and value of the active variant of \a value. If
the active type is std::monostate a default QVariant is returned.
\note With this method you do not need to register the variant as a Qt metatype,
since the std::variant is resolved before being stored. The component types
should be registered however.
\sa fromValue()
*/
/*!
\fn template<typename T> QVariant qVariantFromValue(const T &value)
\relates QVariant

View File

@ -53,6 +53,10 @@
#include <QtCore/qbytearraylist.h>
#endif
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
#include <variant>
#endif
QT_BEGIN_NAMESPACE
@ -355,6 +359,16 @@ class Q_CORE_EXPORT QVariant
static inline QVariant fromValue(const T &value)
{ return qVariantFromValue(value); }
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
template<typename... Types>
static inline QVariant fromStdVariant(const std::variant<Types...> &value)
{
if (value.valueless_by_exception())
return QVariant();
return std::visit([](const auto &arg) { return fromValue(arg); }, value);
}
#endif
template<typename T>
bool canConvert() const
{ return canConvert(qMetaTypeId<T>()); }
@ -503,6 +517,11 @@ inline QVariant qVariantFromValue(const T &t)
template <>
inline QVariant qVariantFromValue(const QVariant &t) { return t; }
#if QT_HAS_INCLUDE(<variant>) && __cplusplus >= 201703L
template <>
inline QVariant qVariantFromValue(const std::monostate &) { return QVariant(); }
#endif
template <typename T>
inline void qVariantSetValue(QVariant &v, const T &t)
{

View File

@ -466,6 +466,8 @@ QStringList QMimeType::suffixes() const
*/
QString QMimeType::preferredSuffix() const
{
if (isDefault()) // workaround for unwanted *.bin suffix for octet-stream, https://bugs.freedesktop.org/show_bug.cgi?id=101667, fixed upstream in 1.10
return QString();
const QStringList suffixList = suffixes();
return suffixList.isEmpty() ? QString() : suffixList.at(0);
}

View File

@ -54,6 +54,8 @@
#include "qjsonobject.h"
#include "qjsonarray.h"
#include <qtcore_tracepoints_p.h>
QT_BEGIN_NAMESPACE
class QFactoryLoaderPrivate : public QObjectPrivate
@ -142,6 +144,9 @@ void QFactoryLoader::update()
if (qt_debug_component()) {
qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName;
}
Q_TRACE(qfactoryloader_update, fileName);
library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
if (!library->isPlugin()) {
if (qt_debug_component()) {

View File

@ -64,6 +64,8 @@
#include "qelfparser_p.h"
#include "qmachparser_p.h"
#include <qtcore_tracepoints_p.h>
QT_BEGIN_NAMESPACE
#ifdef QT_NO_DEBUG
@ -535,6 +537,8 @@ bool QLibraryPrivate::load()
if (fileName.isEmpty())
return false;
Q_TRACE(qlibraryprivate_load_entry, fileName);
bool ret = load_sys();
if (qt_debug_component()) {
if (ret) {
@ -551,6 +555,8 @@ bool QLibraryPrivate::load()
installCoverageTool(this);
}
Q_TRACE(qlibraryprivate_load_exit, ret);
return ret;
}

View File

@ -149,7 +149,6 @@ static QUuid _q_uuidFromHex(const char *src)
return QUuid();
}
#ifndef QT_BOOTSTRAPPED
static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCryptographicHash::Algorithm algorithm, int version)
{
QByteArray hashResult;
@ -172,7 +171,6 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
return result;
}
#endif
/*!
\class QUuid
@ -510,12 +508,12 @@ QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData)
{
return createFromName(ns, baseData, QCryptographicHash::Md5, 3);
}
#endif
QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData)
{
return createFromName(ns, baseData, QCryptographicHash::Sha1, 5);
}
#endif
/*!
Creates a QUuid object from the binary representation of the UUID, as

View File

@ -201,18 +201,20 @@ public:
static QUuid createUuid();
#ifndef QT_BOOTSTRAPPED
static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData);
#endif
static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData);
#ifndef QT_BOOTSTRAPPED
static inline QUuid createUuidV3(const QUuid &ns, const QString &baseData)
{
return QUuid::createUuidV3(ns, baseData.toUtf8());
}
#endif
static inline QUuid createUuidV5(const QUuid &ns, const QString &baseData)
{
return QUuid::createUuidV5(ns, baseData.toUtf8());
}
#endif
QUuid::Variant variant() const Q_DECL_NOTHROW;
QUuid::Version version() const Q_DECL_NOTHROW;

View File

@ -0,0 +1,5 @@
qcoreapplicationprivate_init_entry()
qcoreapplicationprivate_init_exit()
qfactoryloader_update(const QString &fileName)
qlibraryprivate_load_entry(const QString &fileName)
qlibraryprivate_load_exit(bool success)

View File

@ -154,14 +154,7 @@ static inline bool useCompressed(const QString &s)
{
if (s.length() >= 0x8000)
return false;
const ushort *uc = (const ushort *)s.constData();
const ushort *e = uc + s.length();
while (uc < e) {
if (*uc > 0xff)
return false;
++uc;
}
return true;
return QtPrivate::isLatin1(s);
}
static inline int qStringSize(const QString &string, bool compress)

View File

@ -409,6 +409,11 @@ QXmlStreamReader::QXmlStreamReader(const QByteArray &data)
/*!
Creates a new stream reader that reads from \a data.
This function should only be used if the XML header either says the encoding
is "UTF-8" or lacks any encoding information (the latter is the case of
QXmlStreamWriter writing to a QString). Any other encoding is likely going to
cause data corruption ("mojibake").
\sa addData(), clear(), setDevice()
*/
QXmlStreamReader::QXmlStreamReader(const QString &data)
@ -3268,6 +3273,9 @@ QXmlStreamWriter::QXmlStreamWriter(QByteArray *array)
/*! Constructs a stream writer that writes into \a string.
*
* Note that when writing to QString, QXmlStreamWriter ignores the codec set
* with setCodec(). See that function for more information.
*/
QXmlStreamWriter::QXmlStreamWriter(QString *string)
: d_ptr(new QXmlStreamWriterPrivate(this))
@ -3326,6 +3334,12 @@ QIODevice *QXmlStreamWriter::device() const
gets written when you call writeStartDocument(). Call this
function before calling writeStartDocument().
\note When writing the XML to a QString, the codec information is ignored
and the XML header will not include any encoding information, since all
QStrings are UTF-16. If you later convert the QString to an 8-bit format,
you must arrange for the encoding information to be transmitted
out-of-band.
\sa codec()
*/
void QXmlStreamWriter::setCodec(QTextCodec *codec)
@ -3345,6 +3359,12 @@ void QXmlStreamWriter::setCodec(QTextCodec *codec)
"ISO 8859-1", "UTF-8", and "UTF-16". If the encoding isn't
recognized, nothing happens.
\note When writing the XML to a QString, the codec information is ignored
and the XML header will not include any encoding information, since all
QStrings are UTF-16. If you later convert the QString to an 8-bit format,
you must arrange for the encoding information to be transmitted
out-of-band.
\sa QTextCodec::codecForName()
*/
void QXmlStreamWriter::setCodec(const char *codecName)

View File

@ -0,0 +1,30 @@
# Qt data formats core module
HEADERS += \
serialization/qdatastream.h \
serialization/qdatastream_p.h \
serialization/qjson_p.h \
serialization/qjsondocument.h \
serialization/qjsonobject.h \
serialization/qjsonvalue.h \
serialization/qjsonarray.h \
serialization/qjsonwriter_p.h \
serialization/qjsonparser_p.h \
serialization/qtextstream.h \
serialization/qtextstream_p.h \
serialization/qxmlstream.h \
serialization/qxmlstream_p.h \
serialization/qxmlutils_p.h
SOURCES += \
serialization/qdatastream.cpp \
serialization/qjson.cpp \
serialization/qjsondocument.cpp \
serialization/qjsonobject.cpp \
serialization/qjsonarray.cpp \
serialization/qjsonvalue.cpp \
serialization/qjsonwriter.cpp \
serialization/qjsonparser.cpp \
serialization/qtextstream.cpp \
serialization/qxmlstream.cpp \
serialization/qxmlutils.cpp

View File

@ -311,16 +311,14 @@ void QThreadPrivate::createEventDispatcher(QThreadData *data)
#ifndef QT_NO_THREAD
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
static void setCurrentThreadName(pthread_t threadId, const char *name)
static void setCurrentThreadName(const char *name)
{
# if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
Q_UNUSED(threadId);
prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
# elif defined(Q_OS_MAC)
Q_UNUSED(threadId);
pthread_setname_np(name);
# elif defined(Q_OS_QNX)
pthread_setname_np(threadId, name);
pthread_setname_np(pthread_self(), name);
# endif
}
#endif
@ -361,14 +359,13 @@ void *QThreadPrivate::start(void *arg)
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
{
// sets the name of the current thread.
QString objectName = thr->objectName();
pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId.load());
if (Q_LIKELY(objectName.isEmpty()))
setCurrentThreadName(thread_id, thr->metaObject()->className());
// Sets the name of the current thread. We can only do this
// when the thread is starting, as we don't have a cross
// platform way of setting the name of an arbitrary thread.
if (Q_LIKELY(thr->objectName().isEmpty()))
setCurrentThreadName(thr->metaObject()->className());
else
setCurrentThreadName(thread_id, objectName.toLocal8Bit());
setCurrentThreadName(thr->objectName().toLocal8Bit());
}
#endif

View File

@ -300,6 +300,46 @@ void QBitArray::fill(bool value, int begin, int end)
setBit(begin++, value);
}
/*!
\fn const char *QBitArray::bits() const
\since 5.11
Returns a pointer to a dense bit array for this QBitArray. Bits are counted
upwards from the least significant bit in each byte. The the number of bits
relevant in the last byte is given by \c{size() % 8}.
\sa fromBits(), size()
*/
/*!
\since 5.11
Creates a QBitArray with the dense bit array located at \a data, with \a
len bits. The byte array at \a data must be at least \a size / 8 (rounded up)
bytes long.
If \a size is not a multiple of 8, this function will include the lowest
\a size % 8 bits from the last byte in \a data.
\sa bits()
*/
QBitArray QBitArray::fromBits(const char *data, qsizetype size)
{
QBitArray result;
qsizetype nbytes = (size + 7) / 8;
result.d = QByteArray(nbytes + 1, Qt::Uninitialized);
char *bits = result.d.data();
memcpy(bits + 1, data, nbytes);
// clear any unused bits from the last byte
if (size & 7)
bits[nbytes] &= 0xffU >> (size & 7);
*bits = result.d.size() * 8 - size;
return result;
}
/*! \fn bool QBitArray::isDetached() const
\internal

View File

@ -104,6 +104,9 @@ public:
inline void truncate(int pos) { if (pos < size()) resize(pos); }
const char *bits() const { return isEmpty() ? nullptr : d.constData() + 1; }
static QBitArray fromBits(const char *data, qsizetype len);
public:
typedef QByteArray::DataPtr DataPtr;
inline DataPtr &data_ptr() { return d.data_ptr(); }

View File

@ -177,55 +177,37 @@
# define QT_FUNCTION_TARGET(x)
#endif
#if defined(Q_CC_MSVC) && (defined(_M_AVX) || defined(__AVX__))
#ifdef Q_PROCESSOR_X86
/* -- x86 intrinsic support -- */
# if defined(Q_CC_MSVC) && (defined(_M_X64) || _M_IX86_FP >= 2)
// MSVC doesn't define __SSE2__, so do it ourselves
# define __SSE__ 1
# define __SSE2__ 1
# endif
# ifdef __SSE2__
// #include the intrinsics
# include <immintrin.h>
# endif
# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
// GCC 4.4 and Clang 2.8 added a few more intrinsics there
# include <x86intrin.h>
# endif
# if defined(Q_CC_MSVC) && (defined(_M_AVX) || defined(__AVX__))
// Visual Studio defines __AVX__ when /arch:AVX is passed, but not the earlier macros
// See: https://msdn.microsoft.com/en-us/library/b0084kay.aspx
// SSE2 is handled by _M_IX86_FP below
# define __SSE3__ 1
# define __SSSE3__ 1
# define __SSE3__ 1
# define __SSSE3__ 1
// no Intel CPU supports SSE4a, so don't define it
# define __SSE4_1__ 1
# define __SSE4_2__ 1
# ifndef __AVX__
# define __AVX__ 1
# define __SSE4_1__ 1
# define __SSE4_2__ 1
# ifndef __AVX__
# define __AVX__ 1
# endif
# endif
#endif
// SSE intrinsics
#if defined(__SSE2__) || (defined(QT_COMPILER_SUPPORTS_SSE2) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
#if defined(QT_LINUXBASE)
/// this is an evil hack - the posix_memalign declaration in LSB
/// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431
# define posix_memalign _lsb_hack_posix_memalign
# include <emmintrin.h>
# undef posix_memalign
#else
# include <emmintrin.h>
#endif
#if defined(Q_CC_MSVC) && (defined(_M_X64) || _M_IX86_FP >= 2)
# define __SSE__ 1
# define __SSE2__ 1
#endif
#endif
// SSE3 intrinsics
#if defined(__SSE3__) || (defined(QT_COMPILER_SUPPORTS_SSE3) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
#include <pmmintrin.h>
#endif
// SSSE3 intrinsics
#if defined(__SSSE3__) || (defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
#include <tmmintrin.h>
#endif
// SSE4.1 intrinsics
#if defined(__SSE4_1__) || (defined(QT_COMPILER_SUPPORTS_SSE4_1) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
#include <smmintrin.h>
#endif
// SSE4.2 intrinsics
#if defined(__SSE4_2__) || (defined(QT_COMPILER_SUPPORTS_SSE4_2) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
#include <nmmintrin.h>
# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
// POPCNT instructions:
@ -233,13 +215,8 @@
// (but neither MSVC nor the Intel compiler define this macro)
# define __POPCNT__ 1
# endif
#endif
// AVX intrinsics
#if defined(__AVX__) || (defined(QT_COMPILER_SUPPORTS_AVX) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
// immintrin.h is the ultimate header, we don't need anything else after this
#include <immintrin.h>
# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
// AES, PCLMULQDQ instructions:
// All processors that support AVX support AES, PCLMULQDQ
@ -255,11 +232,6 @@
# define __F16C__ 1
# define __RDRND__ 1
# endif
#endif
#if defined(__AES__) || defined(__PCLMUL__) || (defined(QT_COMPILER_SUPPORTS_AES) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS))
# include <wmmintrin.h>
#endif
#define QT_FUNCTION_TARGET_STRING_SSE2 "sse2"
#define QT_FUNCTION_TARGET_STRING_SSE3 "sse3"
@ -288,19 +260,7 @@
#define QT_FUNCTION_TARGET_STRING_RDSEED "rdseed"
#define QT_FUNCTION_TARGET_STRING_SHA "sha"
// other x86 intrinsics
#if defined(Q_PROCESSOR_X86) && ((defined(Q_CC_GNU) && (Q_CC_GNU >= 404)) \
|| (defined(Q_CC_CLANG) && (Q_CC_CLANG >= 208)) \
|| defined(Q_CC_INTEL))
# define QT_COMPILER_SUPPORTS_X86INTRIN
# ifdef Q_CC_INTEL
// The Intel compiler has no <x86intrin.h> -- all intrinsics are in <immintrin.h>;
# include <immintrin.h>
# else
// GCC 4.4 and Clang 2.8 added a few more intrinsics there
# include <x86intrin.h>
# endif
#endif
#endif /* Q_PROCESSOR_X86 */
// Clang compiler fix, see http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160222/151168.html
// This should be tweaked with an "upper version" of clang once we know which release fixes the

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -251,6 +251,151 @@ inline RetType UnrollTailLoop<0>::exec(Number, RetType returnIfExited, Functor1,
}
#endif
#ifdef __SSE2__
static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval)
{
# if defined(__AVX2__)
// AVX2 implementation: test 32 bytes at a time
const __m256i mask256 = _mm256_broadcastd_epi32(_mm_cvtsi32_si128(maskval));
while (ptr + 32 < end) {
__m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr));
if (!_mm256_testz_si256(mask256, data))
return false;
ptr += 32;
}
const __m128i mask = _mm256_castsi256_si128(mask256);
# elif defined(__SSE4_1__)
// SSE 4.1 implementation: test 32 bytes at a time (two 16-byte
// comparisons, unrolled)
const __m128i mask = _mm_set1_epi32(maskval);
while (ptr + 32 < end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
__m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr + 16));
if (!_mm_testz_si128(mask, data1))
return false;
if (!_mm_testz_si128(mask, data2))
return false;
ptr += 32;
}
# endif
# if defined(__SSE4_1__)
// AVX2 and SSE4.1: final 16-byte comparison
if (ptr + 16 < end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
if (!_mm_testz_si128(mask, data1))
return false;
ptr += 16;
}
# else
// SSE2 implementation: test 16 bytes at a time.
const __m128i mask = _mm_set1_epi32(maskval);
while (ptr + 16 < end) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
__m128i masked = _mm_andnot_si128(mask, data);
__m128i comparison = _mm_cmpeq_epi16(masked, _mm_setzero_si128());
if (quint16(_mm_movemask_epi8(comparison)) != 0xffff)
return false;
ptr += 16;
}
# endif
return true;
}
#endif
bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW
{
const char *ptr = s.begin();
const char *end = s.end();
#if defined(__AVX2__)
if (!simdTestMask(ptr, end, 0x80808080))
return false;
#elif defined(__SSE2__)
// Testing for the high bit can be done efficiently with just PMOVMSKB
while (ptr + 16 < end) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
quint32 mask = _mm_movemask_epi8(data);
if (mask)
return false;
ptr += 16;
}
#endif
while (ptr + 4 < end) {
quint32 data = qFromUnaligned<quint32>(ptr);
if (data & 0x80808080U)
return false;
ptr += 4;
}
while (ptr != end) {
if (quint8(*ptr++) & 0x80)
return false;
}
return true;
}
bool QtPrivate::isAscii(QStringView s) Q_DECL_NOTHROW
{
const QChar *ptr = s.begin();
const QChar *end = s.end();
#ifdef __SSE2__
const char *ptr8 = reinterpret_cast<const char *>(ptr);
const char *end8 = reinterpret_cast<const char *>(end);
if (!simdTestMask(ptr8, end8, 0xff80ff80))
return false;
ptr = reinterpret_cast<const QChar *>(ptr8);
#endif
while (ptr != end) {
if ((*ptr++).unicode() & 0xff80)
return false;
}
return true;
}
bool QtPrivate::isLatin1(QStringView s) Q_DECL_NOTHROW
{
const QChar *ptr = s.begin();
const QChar *end = s.end();
#if defined(__SSE4_1__)
const char *ptr8 = reinterpret_cast<const char *>(ptr);
const char *end8 = reinterpret_cast<const char *>(end);
if (!simdTestMask(ptr8, end8, 0xff00ff00))
return false;
ptr = reinterpret_cast<const QChar *>(ptr8);
#elif defined(__SSE2__)
// Testing if every other byte is non-zero can be done efficiently by
// using PUNPCKHBW (unpack high order bytes) and comparing that to zero.
while (ptr + 32 < end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
__m128i data2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr + 16));
__m128i high = _mm_unpackhi_epi8(data1, data2);
__m128i comparison = _mm_cmpeq_epi16(high, _mm_setzero_si128());
if (_mm_movemask_epi8(comparison))
return false;
ptr += 16;
}
if (ptr + 16 < end) {
__m128i data1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr));
__m128i high = _mm_unpackhi_epi8(data1, data1);
__m128i comparison = _mm_cmpeq_epi16(high, _mm_setzero_si128());
if (_mm_movemask_epi8(comparison))
return false;
}
#endif
while (ptr != end) {
if ((*ptr++).unicode() > 0xff)
return false;
}
return true;
}
// conversion between Latin 1 and UTF-16
void qt_from_latin1(ushort *dst, const char *str, size_t size) Q_DECL_NOTHROW
{
@ -2441,6 +2586,21 @@ QString &QString::remove(int pos, int len)
return *this;
}
template<typename T>
static void removeStringImpl(QString &s, const T &needle, Qt::CaseSensitivity cs)
{
const int needleSize = needle.size();
if (needleSize) {
if (needleSize == 1) {
s.remove(needle.front(), cs);
} else {
int i = 0;
while ((i = s.indexOf(needle, i, cs)) != -1)
s.remove(i, needleSize);
}
}
}
/*!
Removes every occurrence of the given \a str string in this
string, and returns a reference to this string.
@ -2454,11 +2614,27 @@ QString &QString::remove(int pos, int len)
*/
QString &QString::remove(const QString &str, Qt::CaseSensitivity cs)
{
if (str.d->size) {
int i = 0;
while ((i = indexOf(str, i, cs)) != -1)
remove(i, str.d->size);
}
removeStringImpl(*this, str, cs);
return *this;
}
/*!
\since 5.11
\overload
Removes every occurrence of the given \a str string in this
string, and returns a reference to this string.
If \a cs is Qt::CaseSensitive (default), the search is
case sensitive; otherwise the search is case insensitive.
This is the same as \c replace(str, "", cs).
\sa replace()
*/
QString &QString::remove(QLatin1String str, Qt::CaseSensitivity cs)
{
removeStringImpl(*this, str, cs);
return *this;
}

View File

@ -201,6 +201,12 @@ Q_DECLARE_TYPEINFO(QLatin1String, Q_MOVABLE_TYPE);
// Qt 4.x compatibility
typedef QLatin1String QLatin1Literal;
//
// QLatin1String inline implementations
//
inline bool QtPrivate::isLatin1(QLatin1String) Q_DECL_NOTHROW
{ return true; }
//
// QStringView members that require QLatin1String:
//
@ -477,6 +483,7 @@ public:
QString &remove(int i, int len);
QString &remove(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString &remove(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString &remove(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
QString &replace(int i, int len, QChar after);
QString &replace(int i, int len, const QChar *s, int slen);

View File

@ -82,6 +82,11 @@ Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToLocal8Bit(QStringView str);
Q_REQUIRED_RESULT Q_CORE_EXPORT QVector<uint> convertToUcs4(QStringView str);
Q_REQUIRED_RESULT Q_CORE_EXPORT bool isRightToLeft(QStringView string);
Q_REQUIRED_RESULT Q_CORE_EXPORT bool isAscii(QLatin1String s) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT Q_CORE_EXPORT bool isAscii(QStringView s) Q_DECL_NOTHROW;
Q_REQUIRED_RESULT bool isLatin1(QLatin1String s) Q_DECL_NOTHROW; // in qstring.h
Q_REQUIRED_RESULT Q_CORE_EXPORT bool isLatin1(QStringView s) Q_DECL_NOTHROW;
} // namespace QtPRivate
QT_END_NAMESPACE

View File

@ -725,8 +725,7 @@
vector.
*/
/*!
\fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, const T &value)
/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, const T &value)
\fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, T &&value)
\overload

View File

@ -607,8 +607,7 @@
\sa append(), insert()
*/
/*!
\fn template <typename T> void QVector<T>::insert(int i, const T &value)
/*! \fn template <typename T> void QVector<T>::insert(int i, const T &value)
\fn template <typename T> void QVector<T>::insert(int i, T &&value)
Inserts \a value at index position \a i in the vector. If \a i is

View File

@ -1,10 +0,0 @@
# Qt xml core module
HEADERS += \
xml/qxmlstream.h \
xml/qxmlstream_p.h \
xml/qxmlutils_p.h
SOURCES += \
xml/qxmlstream.cpp \
xml/qxmlutils.cpp

View File

@ -95,3 +95,6 @@ qtConfig(angle) {
qtConfig(egl): CMAKE_EGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_EGL)
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
TRACEPOINT_PROVIDER = $$PWD/qtgui.tracepoints
CONFIG += qt_tracepoints

View File

@ -278,8 +278,24 @@ void QStandardItemPrivate::setItemData(const QMap<int, QVariant> &roles)
if (newValues != values) {
values.swap(newValues);
if (model)
model->d_func()->itemChanged(q);
if (model) {
QVector<int> roleKeys;
roleKeys.reserve(roles.size() + 1);
bool hasEditRole = false;
bool hasDisplayRole = false;
for (auto it = roles.keyBegin(); it != roles.keyEnd(); ++it) {
roleKeys.push_back(*it);
if (*it == Qt::EditRole)
hasEditRole = true;
else if (*it == Qt::DisplayRole)
hasDisplayRole = true;
}
if (hasEditRole && !hasDisplayRole)
roleKeys.push_back(Qt::DisplayRole);
else if (!hasEditRole && hasDisplayRole)
roleKeys.push_back(Qt::EditRole);
model->d_func()->itemChanged(q, roleKeys);
}
}
}
@ -554,7 +570,7 @@ bool QStandardItemPrivate::insertColumns(int column, int count, const QList<QSta
/*!
\internal
*/
void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
void QStandardItemModelPrivate::itemChanged(QStandardItem *item, const QVector<int> &roles)
{
Q_Q(QStandardItemModel);
Q_ASSERT(item);
@ -570,8 +586,8 @@ void QStandardItemModelPrivate::itemChanged(QStandardItem *item)
}
} else {
// Normal item
QModelIndex index = q->indexFromItem(item);
emit q->dataChanged(index, index);
const QModelIndex index = q->indexFromItem(item);
emit q->dataChanged(index, index, roles);
}
}
@ -885,6 +901,9 @@ void QStandardItem::setData(const QVariant &value, int role)
{
Q_D(QStandardItem);
role = (role == Qt::EditRole) ? Qt::DisplayRole : role;
const QVector<int> roles((role == Qt::DisplayRole) ?
QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
QVector<int>({role}));
QVector<QStandardItemData>::iterator it;
for (it = d->values.begin(); it != d->values.end(); ++it) {
if ((*it).role == role) {
@ -896,13 +915,13 @@ void QStandardItem::setData(const QVariant &value, int role)
d->values.erase(it);
}
if (d->model)
d->model->d_func()->itemChanged(this);
d->model->d_func()->itemChanged(this, roles);
return;
}
}
d->values.append(QStandardItemData(role, value));
if (d->model)
d->model->d_func()->itemChanged(this);
d->model->d_func()->itemChanged(this, roles);
}
/*!

View File

@ -419,6 +419,7 @@ public:
bool dropMimeData (const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
Q_SIGNALS:
// ### Qt 6: add changed roles
void itemChanged(QStandardItem *item);
protected:

View File

@ -200,7 +200,7 @@ public:
}
void sort(QStandardItem *parent, int column, Qt::SortOrder order);
void itemChanged(QStandardItem *item);
void itemChanged(QStandardItem *item, const QVector<int> &roles = QVector<int>());
void rowsAboutToBeInserted(QStandardItem *parent, int start, int end);
void columnsAboutToBeInserted(QStandardItem *parent, int start, int end);
void rowsAboutToBeRemoved(QStandardItem *parent, int start, int end);

View File

@ -3761,14 +3761,25 @@ static inline void formatInputMethodEvent(QDebug d, const QInputMethodEvent *e)
static inline void formatInputMethodQueryEvent(QDebug d, const QInputMethodQueryEvent *e)
{
QDebugStateSaver saver(d);
d.noquote();
const Qt::InputMethodQueries queries = e->queries();
d << "QInputMethodQueryEvent(queries=" << showbase << hex << int(queries)
<< noshowbase << dec << ", {";
for (unsigned mask = 1; mask <= Qt::ImTextAfterCursor; mask<<=1) {
for (unsigned mask = 1; mask <= Qt::ImInputItemClipRectangle; mask<<=1) {
if (queries & mask) {
const QVariant value = e->value(static_cast<Qt::InputMethodQuery>(mask));
if (value.isValid())
d << '[' << showbase << hex << mask << noshowbase << dec << '=' << value << "],";
const Qt::InputMethodQuery query = static_cast<Qt::InputMethodQuery>(mask);
const QVariant value = e->value(query);
if (value.isValid()) {
d << '[';
QtDebugUtils::formatQEnum(d, query);
d << '=';
if (query == Qt::ImHints)
QtDebugUtils::formatQFlags(d, Qt::InputMethodHints(value.toInt()));
else
d << value.toString();
d << "],";
}
}
}
d << "})";

View File

@ -111,6 +111,8 @@
# include <QtCore/QLibraryInfo>
#endif // Q_OS_WIN
#include <qtgui_tracepoints_p.h>
#include <ctype.h>
QT_BEGIN_NAMESPACE
@ -1360,6 +1362,8 @@ void QGuiApplicationPrivate::eventDispatcherReady()
void QGuiApplicationPrivate::init()
{
Q_TRACE(qguiapplicationprivate_init_entry);
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
#endif
@ -1522,6 +1526,8 @@ void QGuiApplicationPrivate::init()
if (!QGuiApplicationPrivate::displayName)
QObject::connect(q, &QGuiApplication::applicationNameChanged,
q, &QGuiApplication::applicationDisplayNameChanged);
Q_TRACE(qguiapplicationprivate_init_exit);
}
extern void qt_cleanupFontDatabase();
@ -1756,6 +1762,8 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra
void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{
Q_TRACE(qguiapplicationprivate_processwsevents_entry, e->type);
switch(e->type) {
case QWindowSystemInterfacePrivate::Mouse:
QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
@ -1864,6 +1872,8 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
qWarning() << "Unknown user input event type:" << e->type;
break;
}
Q_TRACE(qguiapplicationprivate_processwsevents_exit, e->type);
}
/*! \internal

View File

@ -418,6 +418,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return QPlatformTheme::defaultThemeHint(QPlatformTheme::UiEffects);
case WheelScrollLines:
return QPlatformTheme::defaultThemeHint(QPlatformTheme::WheelScrollLines);
case MouseQuickSelectionThreshold:
return QPlatformTheme::defaultThemeHint(QPlatformTheme::MouseQuickSelectionThreshold);
}
return 0;

View File

@ -164,6 +164,7 @@ public:
UiEffects,
WheelScrollLines,
ShowShortcutsInContextMenus,
MouseQuickSelectionThreshold
};
virtual QVariant styleHint(StyleHint hint) const;

View File

@ -559,6 +559,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
dist = defaultThemeHint(MouseDoubleClickDistance).toInt(&ok) * 2;
return QVariant(ok ? dist : 10);
}
case MouseQuickSelectionThreshold:
return QVariant(10);
}
return QVariant();
}

View File

@ -117,7 +117,8 @@ public:
WheelScrollLines,
TouchDoubleTapDistance,
ShowShortcutsInContextMenus,
IconFallbackSearchPaths
IconFallbackSearchPaths,
MouseQuickSelectionThreshold
};
enum DialogType {

View File

@ -79,6 +79,7 @@ public:
, m_tabFocusBehavior(-1)
, m_uiEffects(-1)
, m_wheelScrollLines(-1)
, m_mouseQuickSelectionThreshold(-1)
{}
int m_mouseDoubleClickInterval;
@ -90,6 +91,7 @@ public:
int m_tabFocusBehavior;
int m_uiEffects;
int m_wheelScrollLines;
int m_mouseQuickSelectionThreshold;
};
/*!
@ -537,4 +539,38 @@ void QStyleHints::setWheelScrollLines(int scrollLines)
emit wheelScrollLinesChanged(scrollLines);
}
/*!
Sets the mouse quick selection threshold.
\internal
\sa mouseQuickSelectionThreshold()
\since 5.11
*/
void QStyleHints::setMouseQuickSelectionThreshold(int threshold)
{
Q_D(QStyleHints);
if (d->m_mouseQuickSelectionThreshold == threshold)
return;
d->m_mouseQuickSelectionThreshold = threshold;
emit mouseDoubleClickIntervalChanged(threshold);
}
/*!
\property QStyleHints::mouseQuickSelectionThreshold
\brief Quick selection mouse threshold in QLineEdit.
This property defines how much the mouse cursor should be moved along the y axis
to trigger a quick selection during a normal QLineEdit text selection.
If the property value is less than or equal to 0, the quick selection feature is disabled.
\since 5.11
*/
int QStyleHints::mouseQuickSelectionThreshold() const
{
Q_D(const QStyleHints);
if (d->m_mouseQuickSelectionThreshold >= 0)
return d->m_mouseQuickSelectionThreshold;
return themeableHint(QPlatformTheme::MouseQuickSelectionThreshold, QPlatformIntegration::MouseQuickSelectionThreshold).toInt();
}
QT_END_NAMESPACE

View File

@ -73,6 +73,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject
Q_PROPERTY(bool singleClickActivation READ singleClickActivation STORED false CONSTANT FINAL)
Q_PROPERTY(bool useHoverEffects READ useHoverEffects WRITE setUseHoverEffects NOTIFY useHoverEffectsChanged FINAL)
Q_PROPERTY(int wheelScrollLines READ wheelScrollLines NOTIFY wheelScrollLinesChanged FINAL)
Q_PROPERTY(int mouseQuickSelectionThreshold READ mouseQuickSelectionThreshold WRITE setMouseQuickSelectionThreshold NOTIFY mouseQuickSelectionThresholdChanged FINAL)
public:
void setMouseDoubleClickInterval(int mouseDoubleClickInterval);
@ -104,6 +105,8 @@ public:
void setUseHoverEffects(bool useHoverEffects);
int wheelScrollLines() const;
void setWheelScrollLines(int scrollLines);
void setMouseQuickSelectionThreshold(int threshold);
int mouseQuickSelectionThreshold() const;
Q_SIGNALS:
void cursorFlashTimeChanged(int cursorFlashTime);
@ -115,6 +118,7 @@ Q_SIGNALS:
void tabFocusBehaviorChanged(Qt::TabFocusBehavior tabFocusBehavior);
void useHoverEffectsChanged(bool useHoverEffects);
void wheelScrollLinesChanged(int scrollLines);
void mouseQuickSelectionThresholdChanged(int threshold);
private:
friend class QGuiApplication;

View File

@ -174,29 +174,31 @@ template<QImage::Format Format>
static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
auto conversion = [](uint s) {
// MSVC needs these constexpr defined in here otherwise it will create a capture.
Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
for (int i = 0; i < count; ++i) {
uint red = (src[i] >> redShift<Format>()) & redMask;
uint green = (src[i] >> greenShift<Format>()) & greenMask;
uint blue = (src[i] >> blueShift<Format>()) & blueMask;
uint red = (s >> redShift<Format>()) & redMask;
uint green = (s >> greenShift<Format>()) & greenMask;
uint blue = (s >> blueShift<Format>()) & blueMask;
red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
blue = (blue << blueLeftShift) | (blue >> blueRightShift);
buffer[i] = 0xff000000 | red | green | blue;
}
return 0xff000000 | red | green | blue;
};
UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion);
return buffer;
}
@ -348,21 +350,21 @@ static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *
// RGB32 -> RGB888 is not a precision loss.
if (!dither || (rWidth == 8 && gWidth == 8 && bWidth == 8)) {
Q_CONSTEXPR uint rMask = (1 << rWidth) - 1;
Q_CONSTEXPR uint gMask = (1 << gWidth) - 1;
Q_CONSTEXPR uint bMask = (1 << bWidth) - 1;
auto conversion = [](uint s) {
const uint c = fromRGB ? s : qUnpremultiply(s);
Q_CONSTEXPR uint rMask = (1 << redWidth<Format>()) - 1;
Q_CONSTEXPR uint gMask = (1 << greenWidth<Format>()) - 1;
Q_CONSTEXPR uint bMask = (1 << blueWidth<Format>()) - 1;
Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>();
Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>();
Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>();
Q_CONSTEXPR uchar rRightShift = 24 - rWidth;
Q_CONSTEXPR uchar gRightShift = 16 - gWidth;
Q_CONSTEXPR uchar bRightShift = 8 - bWidth;
for (int i = 0; i < count; ++i) {
const uint c = fromRGB ? src[i] : qUnpremultiply(src[i]);
const uint r = ((c >> rRightShift) & rMask) << redShift<Format>();
const uint g = ((c >> gRightShift) & gMask) << greenShift<Format>();
const uint b = ((c >> bRightShift) & bMask) << blueShift<Format>();
buffer[i] = r | g | b;
}
return r | g | b;
};
UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion);
} else {
// We do ordered dither by using a rounding conversion, but instead of
// adding half of input precision, we add the adjusted result from the
@ -394,32 +396,32 @@ template<QImage::Format Format, bool fromRGB>
static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *dither)
{
Q_CONSTEXPR uchar aWidth = alphaWidth<Format>();
Q_CONSTEXPR uchar rWidth = redWidth<Format>();
Q_CONSTEXPR uchar gWidth = greenWidth<Format>();
Q_CONSTEXPR uchar bWidth = blueWidth<Format>();
if (!dither) {
Q_CONSTEXPR uint aMask = (1 << aWidth) - 1;
Q_CONSTEXPR uint rMask = (1 << rWidth) - 1;
Q_CONSTEXPR uint gMask = (1 << gWidth) - 1;
Q_CONSTEXPR uint bMask = (1 << bWidth) - 1;
auto conversion = [](uint c) {
Q_CONSTEXPR uint aMask = (1 << alphaWidth<Format>()) - 1;
Q_CONSTEXPR uint rMask = (1 << redWidth<Format>()) - 1;
Q_CONSTEXPR uint gMask = (1 << greenWidth<Format>()) - 1;
Q_CONSTEXPR uint bMask = (1 << blueWidth<Format>()) - 1;
Q_CONSTEXPR uchar aRightShift = 32 - aWidth;
Q_CONSTEXPR uchar rRightShift = 24 - rWidth;
Q_CONSTEXPR uchar gRightShift = 16 - gWidth;
Q_CONSTEXPR uchar bRightShift = 8 - bWidth;
Q_CONSTEXPR uchar aRightShift = 32 - alphaWidth<Format>();
Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>();
Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>();
Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>();
Q_CONSTEXPR uint aOpaque = aMask << alphaShift<Format>();
for (int i = 0; i < count; ++i) {
const uint c = src[i];
Q_CONSTEXPR uint aOpaque = aMask << alphaShift<Format>();
const uint a = fromRGB ? aOpaque : (((c >> aRightShift) & aMask) << alphaShift<Format>());
const uint r = ((c >> rRightShift) & rMask) << redShift<Format>();
const uint g = ((c >> gRightShift) & gMask) << greenShift<Format>();
const uint b = ((c >> bRightShift) & bMask) << blueShift<Format>();
buffer[i] = a | r | g | b;
}
return a | r | g | b;
};
UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion);
} else {
Q_CONSTEXPR uchar aWidth = alphaWidth<Format>();
Q_CONSTEXPR uchar rWidth = redWidth<Format>();
Q_CONSTEXPR uchar gWidth = greenWidth<Format>();
Q_CONSTEXPR uchar bWidth = blueWidth<Format>();
const uint *bayer_line = qt_bayer_matrix[dither->y & 15];
for (int i = 0; i < count; ++i) {
const uint c = src[i];
@ -514,8 +516,7 @@ static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint
static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
buffer[i] = RGBA2ARGB(src[i]);
UNALIASED_CONVERSION_LOOP(buffer, src, count, RGBA2ARGB);
return buffer;
}
@ -568,8 +569,7 @@ static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uin
static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
buffer[i] = ARGB2RGBA(src[i]);
UNALIASED_CONVERSION_LOOP(buffer, src, count, ARGB2RGBA);
return buffer;
}
@ -695,8 +695,7 @@ static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const u
static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
buffer[i] = ARGB2RGBA(0xff000000 | src[i]);
UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint c) { return ARGB2RGBA(0xff000000 | c); });
return buffer;
}
@ -713,8 +712,7 @@ static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const ui
const QVector<QRgb> *, QDitherInfo *dither)
{
if (!dither) {
for (int i = 0; i < count; ++i)
buffer[i] = qConvertA2rgb30ToArgb32<PixelOrder>(src[i]);
UNALIASED_CONVERSION_LOOP(buffer, src, count, qConvertA2rgb30ToArgb32<PixelOrder>);
} else {
for (int i = 0; i < count; ++i) {
const uint c = src[i];
@ -796,8 +794,7 @@ template<QtPixelOrder PixelOrder>
static const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
buffer[i] = qConvertArgb32ToA2rgb30<PixelOrder>(src[i]);
UNALIASED_CONVERSION_LOOP(buffer, src, count, qConvertArgb32ToA2rgb30<PixelOrder>);
return buffer;
}
@ -814,8 +811,7 @@ template<QtPixelOrder PixelOrder>
static const uint *QT_FASTCALL convertRGB30FromARGB32PM(uint *buffer, const uint *src, int count,
const QVector<QRgb> *, QDitherInfo *)
{
for (int i = 0; i < count; ++i)
buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(src[i]));
UNALIASED_CONVERSION_LOOP(buffer, src, count, qConvertRgb32ToRgb30<PixelOrder>);
return buffer;
}

View File

@ -427,7 +427,7 @@ void QT_FASTCALL comp_func_Source_rgb64_avx2(QRgba64 *dst, const QRgba64 *src, i
::memcpy(dst, src, length * sizeof(QRgba64));
} else {
const uint ca = const_alpha | (const_alpha << 8); // adjust to [0-65535]
const uint cia = 65535 - const_alpha;
const uint cia = 65535 - ca;
int x = 0;
@ -493,7 +493,7 @@ void QT_FASTCALL comp_func_solid_SourceOver_rgb64_avx2(QRgba64 *destPixels, int
if (const_alpha != 255)
color = multiplyAlpha255(color, const_alpha);
const uint minusAlphaOfColor = ~ushort(color.alpha());
const uint minusAlphaOfColor = 65535 - color.alpha();
int x = 0;
quint64 *dst = (quint64 *) destPixels;
const __m256i colorVector = _mm256_set1_epi64x(color);

View File

@ -1104,22 +1104,30 @@ inline int qBlue565(quint16 rgb) {
return (b << 3) | (b >> 2);
}
// We manually unalias the variables to make sure the compiler
// fully optimizes both aliased and unaliased cases.
#define UNALIASED_CONVERSION_LOOP(buffer, src, count, conversion) \
if (src == buffer) { \
for (int i = 0; i < count; ++i) \
buffer[i] = conversion(buffer[i]); \
} else { \
for (int i = 0; i < count; ++i) \
buffer[i] = conversion(src[i]); \
}
static Q_ALWAYS_INLINE const uint *qt_convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count)
{
for (int i = 0; i < count; ++i)
buffer[i] = qPremultiply(src[i]);
UNALIASED_CONVERSION_LOOP(buffer, src, count, qPremultiply);
return buffer;
}
static Q_ALWAYS_INLINE const uint *qt_convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count)
{
for (int i = 0; i < count; ++i)
buffer[i] = qPremultiply(RGBA2ARGB(src[i]));
UNALIASED_CONVERSION_LOOP(buffer, src, count, [](uint s) { return qPremultiply(RGBA2ARGB(s));});
return buffer;
}
const uint qt_bayer_matrix[16][16] = {
{ 0x1, 0xc0, 0x30, 0xf0, 0xc, 0xcc, 0x3c, 0xfc,
0x3, 0xc3, 0x33, 0xf3, 0xf, 0xcf, 0x3f, 0xff},

View File

@ -0,0 +1,8 @@
qfontdatabase_addapplicationfont(const QString &filename)
qfontdatabase_load(const QString &family, int pointSize)
qfontdatabase_loadengine(const QString &family, int pointSize)
qfontdatabaseprivate_addappfont(const QString &fileName)
qguiapplicationprivate_init_entry()
qguiapplicationprivate_init_exit()
qguiapplicationprivate_processwsevents_entry(int type)
qguiapplicationprivate_processwsevents_exit(int type)

View File

@ -74,6 +74,7 @@
# define FM_DEBUG if (false) qDebug
#endif
#include <qtgui_tracepoints_p.h>
QT_BEGIN_NAMESPACE
@ -1009,6 +1010,8 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
Q_TRACE(qfontdatabase_loadengine, request.family, request.pointSize);
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
if (!request.fallBackFamilies.isEmpty()) {
@ -2439,6 +2442,8 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
font.data = fontData;
font.fileName = fileName;
Q_TRACE(qfontdatabaseprivate_addappfont, fileName);
int i;
for (i = 0; i < applicationFonts.count(); ++i)
if (applicationFonts.at(i).families.isEmpty())
@ -2494,6 +2499,9 @@ int QFontDatabase::addApplicationFont(const QString &fileName)
QFile f(fileName);
if (!f.open(QIODevice::ReadOnly))
return -1;
Q_TRACE(qfontdatabase_addapplicationfont, fileName);
data = f.readAll();
}
QMutexLocker locker(fontDatabaseMutex());
@ -2792,6 +2800,8 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QFontEngine *fe = nullptr;
Q_TRACE(qfontdatabase_load, req.family, req.pointSize);
req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
req.family = req.fallBackFamilies.takeFirst();

View File

@ -308,7 +308,7 @@ QT_BEGIN_NAMESPACE
was specified, QNetworkAccessManager gives up, without attempting to
fall back to HTTP/1.1. If both HTTP2AllowedAttribute and
Http2DirectAttribute are set, Http2DirectAttribute takes priority.
(This value was introduced in 5.10.)
(This value was introduced in 5.11.)
\omitvalue ResourceTypeAttribute

View File

@ -221,6 +221,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->peerVerifyMode == other.d->peerVerifyMode &&
d->peerVerifyDepth == other.d->peerVerifyDepth &&
d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
d->backendConfig == other.d->backendConfig &&
d->sslOptions == other.d->sslOptions &&
d->sslSession == other.d->sslSession &&
d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint &&
@ -263,6 +264,7 @@ bool QSslConfiguration::isNull() const
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
d->backendConfig.isEmpty() &&
d->sslOptions == QSslConfigurationPrivate::defaultSslOptions &&
d->sslSession.isNull() &&
d->sslSessionTicketLifeTimeHint == -1 &&
@ -869,6 +871,60 @@ void QSslConfiguration::setDiffieHellmanParameters(const QSslDiffieHellmanParame
d->dhParams = dhparams;
}
/*!
\since 5.11
Returns the backend-specific configuration.
Only options set by addBackendConfig() or setBackendConfig() will be
returned. The internal standard configuration of the backend is not reported.
\sa setBackendConfigOption(), setBackendConfig()
*/
QMap<QByteArray, QVariant> QSslConfiguration::backendConfig() const
{
return d->backendConfig;
}
/*!
\since 5.11
Sets an option in the backend-specific configuration.
Options supported by the OpenSSL (>= 1.0.2) backend are available in the \l
{https://www.openssl.org/docs/manmaster/man3/SSL_CONF_cmd.html#SUPPORTED-CONFIGURATION-FILE-COMMANDS}
{supported configuration file commands} documentation. The expected type for
the \a value parameter is a QByteArray for all options. The \l
{https://www.openssl.org/docs/manmaster/man3/SSL_CONF_cmd.html#EXAMPLES}{examples}
show how to use some of the options.
\note The backend-specific configuration will be applied after the general
configuration. Using the backend-specific configuration to set a general
configuration option again will overwrite the general configuration option.
\sa backendConfig(), setBackendConfig()
*/
void QSslConfiguration::setBackendConfigOption(const QByteArray &name, const QVariant &value)
{
d->backendConfig[name] = value;
}
/*!
\since 5.11
Sets or clears the backend-specific configuration.
Without a \a backendConfig parameter this function will clear the
backend-specific configuration. More information about the supported
options is available in the documentation of addBackendConfig().
\sa backendConfig(), setBackendConfigOption()
*/
void QSslConfiguration::setBackendConfig(const QMap<QByteArray, QVariant> &backendConfig)
{
d->backendConfig = backendConfig;
}
/*!
\since 5.3

View File

@ -57,6 +57,7 @@
#define QSSLCONFIGURATION_H
#include <QtNetwork/qtnetworkglobal.h>
#include <QtCore/qmap.h>
#include <QtCore/qshareddata.h>
#include <QtNetwork/qsslsocket.h>
#include <QtNetwork/qssl.h>
@ -149,6 +150,10 @@ public:
QSslDiffieHellmanParameters diffieHellmanParameters() const;
void setDiffieHellmanParameters(const QSslDiffieHellmanParameters &dhparams);
QMap<QByteArray, QVariant> backendConfig() const;
void setBackendConfigOption(const QByteArray &name, const QVariant &value);
void setBackendConfig(const QMap<QByteArray, QVariant> &backendConfig = QMap<QByteArray, QVariant>());
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);

View File

@ -67,6 +67,7 @@
// We mean it.
//
#include <QtCore/qmap.h>
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include "qsslconfiguration.h"
#include "qlist.h"
@ -123,6 +124,8 @@ public:
QSslDiffieHellmanParameters dhParams;
QMap<QByteArray, QVariant> backendConfig;
QByteArray sslSession;
int sslSessionTicketLifeTimeHint;

View File

@ -49,6 +49,11 @@
QT_BEGIN_NAMESPACE
static inline QString msgErrorSettingBackendConfig(const QString &why)
{
return QSslSocket::tr("Error when setting the OpenSSL configuration (%1)").arg(why);
}
QSslContext::QSslContext()
: ctx(0),
pkey(0),
@ -237,4 +242,70 @@ QString QSslContext::errorString() const
return errorStr;
}
// static
void QSslContext::applyBackendConfig(QSslContext *sslContext)
{
if (sslContext->sslConfiguration.backendConfig().isEmpty())
return;
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) {
QSharedPointer<SSL_CONF_CTX> cctx(q_SSL_CONF_CTX_new(), &q_SSL_CONF_CTX_free);
if (cctx) {
q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx);
q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE);
const auto &backendConfig = sslContext->sslConfiguration.backendConfig();
for (auto i = backendConfig.constBegin(); i != backendConfig.constEnd(); ++i) {
if (!i.value().canConvert(QMetaType::QByteArray)) {
sslContext->errorCode = QSslError::UnspecifiedError;
sslContext->errorStr = msgErrorSettingBackendConfig(
QSslSocket::tr("Expecting QByteArray for %1").arg(
QString::fromUtf8(i.key())));
return;
}
const QByteArray &value = i.value().toByteArray();
const int result = q_SSL_CONF_cmd(cctx.data(), i.key().constData(), value.constData());
if (result == 2)
continue;
sslContext->errorCode = QSslError::UnspecifiedError;
switch (result) {
case 0:
sslContext->errorStr = msgErrorSettingBackendConfig(
QSslSocket::tr("An error occurred attempting to set %1 to %2").arg(
QString::fromUtf8(i.key()), QString::fromUtf8(value)));
return;
case 1:
sslContext->errorStr = msgErrorSettingBackendConfig(
QSslSocket::tr("Wrong value for %1 (%2)").arg(
QString::fromUtf8(i.key()), QString::fromUtf8(value)));
return;
default:
sslContext->errorStr = msgErrorSettingBackendConfig(
QSslSocket::tr("Unrecognized command %1 = %2").arg(
QString::fromUtf8(i.key()), QString::fromUtf8(value)));
return;
}
}
if (q_SSL_CONF_CTX_finish(cctx.data()) == 0) {
sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_finish() failed"));
sslContext->errorCode = QSslError::UnspecifiedError;
}
} else {
sslContext->errorStr = msgErrorSettingBackendConfig(QSslSocket::tr("SSL_CONF_CTX_new() failed"));
sslContext->errorCode = QSslError::UnspecifiedError;
}
} else
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
{
// specific algorithms requested, but not possible to set
sslContext->errorCode = QSslError::UnspecifiedError;
sslContext->errorStr = msgErrorSettingBackendConfig(
QSslSocket::tr("OpenSSL version too old, need at least v1.0.2"));
}
}
QT_END_NAMESPACE

View File

@ -260,6 +260,7 @@ init_context:
#ifdef OPENSSL_NO_EC
sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version with disabled elliptic curves"));
sslContext->errorCode = QSslError::UnspecifiedError;
return;
#else
// Set the curves to be used.
std::vector<int> curves;
@ -269,9 +270,12 @@ init_context:
if (!q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_CURVES, long(curves.size()), &curves[0])) {
sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl());
sslContext->errorCode = QSslError::UnspecifiedError;
return;
}
#endif
}
applyBackendConfig(sslContext);
}
QT_END_NAMESPACE

Some files were not shown because too many files have changed in this diff Show More