1 | // Copyright (C) 2017 The Qt Company Ltd. |
2 | // Copyright (C) 2015 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QGLOBAL_P_H |
6 | #define QGLOBAL_P_H |
7 | |
8 | // |
9 | // W A R N I N G |
10 | // ------------- |
11 | // |
12 | // This file is not part of the Qt API. It exists purely as an |
13 | // implementation detail. This header file may change from version to |
14 | // version without notice, or even be removed. |
15 | // |
16 | // We mean it. |
17 | // |
18 | |
19 | #include "qglobal.h" |
20 | #include "qglobal_p.h" // include self to avoid syncqt warning - no-op |
21 | |
22 | #ifndef QT_BOOTSTRAPPED |
23 | #include <QtCore/private/qconfig_p.h> |
24 | #include <QtCore/private/qtcore-config_p.h> |
25 | #endif |
26 | |
27 | #if defined(Q_CC_MSVC) |
28 | // By default, dynamic initialization uses subsection "$XCU", which is |
29 | // equivalent to #pragma init_seg(user). Additionally, #pragma |
30 | // init_seg(compiler) and init_seg(lib) use "$XCC" and "$XCL" respectively. So |
31 | // place us between "compiler" and "lib". |
32 | # define QT_SUPPORTS_INIT_PRIORITY 1 |
33 | |
34 | // warning C4075: initializers put in unrecognized initialization area |
35 | # define Q_DECL_INIT_PRIORITY(nn) \ |
36 | __pragma(warning(disable: 4075)) \ |
37 | __pragma(init_seg(".CRT$XCK" QT_STRINGIFY(nn))) Q_DECL_UNUSED |
38 | #elif defined(Q_OS_QNX) |
39 | // init_priority fails on QNX and we didn't bother investigating why |
40 | # define QT_SUPPORTS_INIT_PRIORITY 0 |
41 | #elif defined(Q_OS_WIN) || defined(Q_OF_ELF) |
42 | # define QT_SUPPORTS_INIT_PRIORITY 1 |
43 | // priorities 0 to 1000 are reserved to the runtime; |
44 | // we use above 2000 in case someone REALLY needs to go before us |
45 | # define Q_DECL_INIT_PRIORITY(nn) __attribute__((init_priority(2000 + nn), used)) |
46 | #elif defined(QT_SHARED) |
47 | // it doesn't support this exactly, but we can work around it |
48 | # define QT_SUPPORTS_INIT_PRIORITY -1 |
49 | # define Q_DECL_INIT_PRIORITY(nn) Q_DECL_UNUSED |
50 | #else |
51 | # define QT_SUPPORTS_INIT_PRIORITY 0 |
52 | #endif |
53 | |
54 | #if defined(__cplusplus) |
55 | QT_BEGIN_NAMESPACE |
56 | |
57 | Q_NORETURN Q_CORE_EXPORT void qAbort(); |
58 | |
59 | QT_END_NAMESPACE |
60 | |
61 | #if !__has_builtin(__builtin_available) |
62 | #include <initializer_list> |
63 | #include <QtCore/qoperatingsystemversion.h> |
64 | #include <QtCore/qversionnumber.h> |
65 | |
66 | QT_BEGIN_NAMESPACE |
67 | |
68 | struct qt_clang_builtin_available_os_version_data { |
69 | QOperatingSystemVersion::OSType type; |
70 | const char *version; |
71 | }; |
72 | |
73 | static inline bool qt_clang_builtin_available( |
74 | const std::initializer_list<qt_clang_builtin_available_os_version_data> &versions) |
75 | { |
76 | for (auto it = versions.begin(); it != versions.end(); ++it) { |
77 | if (QOperatingSystemVersion::currentType() == it->type) { |
78 | const auto current = QOperatingSystemVersion::current(); |
79 | return QVersionNumber( |
80 | current.majorVersion(), |
81 | current.minorVersion(), |
82 | current.microVersion()) >= QVersionNumber::fromString( |
83 | QString::fromLatin1(it->version)); |
84 | } |
85 | } |
86 | |
87 | // Result is true if the platform is not any of the checked ones; this matches behavior of |
88 | // LLVM __builtin_available and @available constructs |
89 | return true; |
90 | } |
91 | |
92 | QT_END_NAMESPACE |
93 | |
94 | #define QT_AVAILABLE_OS_VER(os, ver) \ |
95 | QT_PREPEND_NAMESPACE(qt_clang_builtin_available_os_version_data){\ |
96 | QT_PREPEND_NAMESPACE(QOperatingSystemVersion)::os, #ver} |
97 | #define QT_AVAILABLE_CAT(L, R) QT_AVAILABLE_CAT_(L, R) |
98 | #define QT_AVAILABLE_CAT_(L, R) L ## R |
99 | #define QT_AVAILABLE_EXPAND(...) QT_AVAILABLE_OS_VER(__VA_ARGS__) |
100 | #define QT_AVAILABLE_SPLIT(os_ver) QT_AVAILABLE_EXPAND(QT_AVAILABLE_CAT(QT_AVAILABLE_SPLIT_, os_ver)) |
101 | #define QT_AVAILABLE_SPLIT_macOS MacOS, |
102 | #define QT_AVAILABLE_SPLIT_iOS IOS, |
103 | #define QT_AVAILABLE_SPLIT_tvOS TvOS, |
104 | #define QT_AVAILABLE_SPLIT_watchOS WatchOS, |
105 | #define QT_BUILTIN_AVAILABLE0(e) \ |
106 | QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({}) |
107 | #define QT_BUILTIN_AVAILABLE1(a, e) \ |
108 | QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a)}) |
109 | #define QT_BUILTIN_AVAILABLE2(a, b, e) \ |
110 | QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \ |
111 | QT_AVAILABLE_SPLIT(b)}) |
112 | #define QT_BUILTIN_AVAILABLE3(a, b, c, e) \ |
113 | QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \ |
114 | QT_AVAILABLE_SPLIT(b), \ |
115 | QT_AVAILABLE_SPLIT(c)}) |
116 | #define QT_BUILTIN_AVAILABLE4(a, b, c, d, e) \ |
117 | QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \ |
118 | QT_AVAILABLE_SPLIT(b), \ |
119 | QT_AVAILABLE_SPLIT(c), \ |
120 | QT_AVAILABLE_SPLIT(d)}) |
121 | #define QT_BUILTIN_AVAILABLE_ARG(arg0, arg1, arg2, arg3, arg4, arg5, ...) arg5 |
122 | #define QT_BUILTIN_AVAILABLE_CHOOSER(...) QT_BUILTIN_AVAILABLE_ARG(__VA_ARGS__, \ |
123 | QT_BUILTIN_AVAILABLE4, \ |
124 | QT_BUILTIN_AVAILABLE3, \ |
125 | QT_BUILTIN_AVAILABLE2, \ |
126 | QT_BUILTIN_AVAILABLE1, \ |
127 | QT_BUILTIN_AVAILABLE0, ) |
128 | #define __builtin_available(...) QT_BUILTIN_AVAILABLE_CHOOSER(__VA_ARGS__)(__VA_ARGS__) |
129 | #endif // !__has_builtin(__builtin_available) |
130 | #endif // defined(__cplusplus) |
131 | |
132 | #endif // QGLOBAL_P_H |
133 | |