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/qtcoreglobal_p.h>
24#endif
25
26#if defined(Q_CC_MSVC)
27// By default, dynamic initialization uses subsection "$XCU", which is
28// equivalent to #pragma init_seg(user). Additionally, #pragma
29// init_seg(compiler) and init_seg(lib) use "$XCC" and "$XCL" respectively. So
30// place us between "compiler" and "lib".
31# define QT_SUPPORTS_INIT_PRIORITY 1
32
33// warning C4075: initializers put in unrecognized initialization area
34# define Q_DECL_INIT_PRIORITY(nn) \
35 __pragma(warning(disable: 4075)) \
36 __pragma(init_seg(".CRT$XCK" QT_STRINGIFY(nn))) Q_DECL_UNUSED
37#elif defined(Q_OS_QNX)
38// init_priority fails on QNX and we didn't bother investigating why
39# define QT_SUPPORTS_INIT_PRIORITY 0
40#elif defined(Q_OS_WIN) || defined(Q_OF_ELF)
41# define QT_SUPPORTS_INIT_PRIORITY 1
42// priorities 0 to 1000 are reserved to the runtime;
43// we use above 2000 in case someone REALLY needs to go before us
44# define Q_DECL_INIT_PRIORITY(nn) __attribute__((init_priority(2000 + nn), used))
45#elif defined(QT_SHARED)
46// it doesn't support this exactly, but we can work around it
47# define QT_SUPPORTS_INIT_PRIORITY -1
48# define Q_DECL_INIT_PRIORITY(nn) Q_DECL_UNUSED
49#else
50# define QT_SUPPORTS_INIT_PRIORITY 0
51#endif
52
53#if defined(__cplusplus)
54QT_BEGIN_NAMESPACE
55
56Q_NORETURN Q_CORE_EXPORT void qAbort();
57
58QT_END_NAMESPACE
59
60#if !__has_builtin(__builtin_available)
61#include <initializer_list>
62#include <QtCore/qoperatingsystemversion.h>
63#include <QtCore/qversionnumber.h>
64
65QT_BEGIN_NAMESPACE
66
67struct qt_clang_builtin_available_os_version_data {
68 QOperatingSystemVersion::OSType type;
69 const char *version;
70};
71
72static inline bool qt_clang_builtin_available(
73 const std::initializer_list<qt_clang_builtin_available_os_version_data> &versions)
74{
75 for (auto it = versions.begin(); it != versions.end(); ++it) {
76 if (QOperatingSystemVersion::currentType() == it->type) {
77 const auto current = QOperatingSystemVersion::current();
78 return QVersionNumber(
79 current.majorVersion(),
80 current.minorVersion(),
81 current.microVersion()) >= QVersionNumber::fromString(
82 QString::fromLatin1(it->version));
83 }
84 }
85
86 // Result is true if the platform is not any of the checked ones; this matches behavior of
87 // LLVM __builtin_available and @available constructs
88 return true;
89}
90
91QT_END_NAMESPACE
92
93#define QT_AVAILABLE_OS_VER(os, ver) \
94 QT_PREPEND_NAMESPACE(qt_clang_builtin_available_os_version_data){\
95 QT_PREPEND_NAMESPACE(QOperatingSystemVersion)::os, #ver}
96#define QT_AVAILABLE_CAT(L, R) QT_AVAILABLE_CAT_(L, R)
97#define QT_AVAILABLE_CAT_(L, R) L ## R
98#define QT_AVAILABLE_EXPAND(...) QT_AVAILABLE_OS_VER(__VA_ARGS__)
99#define QT_AVAILABLE_SPLIT(os_ver) QT_AVAILABLE_EXPAND(QT_AVAILABLE_CAT(QT_AVAILABLE_SPLIT_, os_ver))
100#define QT_AVAILABLE_SPLIT_macOS MacOS,
101#define QT_AVAILABLE_SPLIT_iOS IOS,
102#define QT_AVAILABLE_SPLIT_tvOS TvOS,
103#define QT_AVAILABLE_SPLIT_watchOS WatchOS,
104#define QT_BUILTIN_AVAILABLE0(e) \
105 QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({})
106#define QT_BUILTIN_AVAILABLE1(a, e) \
107 QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a)})
108#define QT_BUILTIN_AVAILABLE2(a, b, e) \
109 QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \
110 QT_AVAILABLE_SPLIT(b)})
111#define QT_BUILTIN_AVAILABLE3(a, b, c, e) \
112 QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \
113 QT_AVAILABLE_SPLIT(b), \
114 QT_AVAILABLE_SPLIT(c)})
115#define QT_BUILTIN_AVAILABLE4(a, b, c, d, e) \
116 QT_PREPEND_NAMESPACE(qt_clang_builtin_available)({QT_AVAILABLE_SPLIT(a), \
117 QT_AVAILABLE_SPLIT(b), \
118 QT_AVAILABLE_SPLIT(c), \
119 QT_AVAILABLE_SPLIT(d)})
120#define QT_BUILTIN_AVAILABLE_ARG(arg0, arg1, arg2, arg3, arg4, arg5, ...) arg5
121#define QT_BUILTIN_AVAILABLE_CHOOSER(...) QT_BUILTIN_AVAILABLE_ARG(__VA_ARGS__, \
122 QT_BUILTIN_AVAILABLE4, \
123 QT_BUILTIN_AVAILABLE3, \
124 QT_BUILTIN_AVAILABLE2, \
125 QT_BUILTIN_AVAILABLE1, \
126 QT_BUILTIN_AVAILABLE0, )
127#define __builtin_available(...) QT_BUILTIN_AVAILABLE_CHOOSER(__VA_ARGS__)(__VA_ARGS__)
128#endif // !__has_builtin(__builtin_available)
129#endif // defined(__cplusplus)
130
131#endif // QGLOBAL_P_H
132

source code of qtbase/src/corelib/global/qglobal_p.h