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)
55QT_BEGIN_NAMESPACE
56
57Q_NORETURN Q_CORE_EXPORT void qAbort();
58
59QT_END_NAMESPACE
60
61#if !__has_builtin(__builtin_available)
62#include <initializer_list>
63#include <QtCore/qoperatingsystemversion.h>
64#include <QtCore/qversionnumber.h>
65
66QT_BEGIN_NAMESPACE
67
68struct qt_clang_builtin_available_os_version_data {
69 QOperatingSystemVersion::OSType type;
70 const char *version;
71};
72
73static 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
92QT_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

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