summaryrefslogtreecommitdiff
path: root/src/util/Compiler.h
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2018-08-20 16:19:17 +0200
committerMax Kellermann <max@musicpd.org>2018-08-20 16:19:17 +0200
commitec54754e22602bbc18a7524b6ff07db2a4b6d095 (patch)
tree2c9208d79cf2a04a6c821c400d5f7336b5c1be42 /src/util/Compiler.h
parent0ebba73cb8d74d18d6af87bbed99e91bac6a4eac (diff)
Compiler.h: move to util/
Diffstat (limited to 'src/util/Compiler.h')
-rw-r--r--src/util/Compiler.h186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/util/Compiler.h b/src/util/Compiler.h
new file mode 100644
index 000000000..d2ca0b8f3
--- /dev/null
+++ b/src/util/Compiler.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2003-2017 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+#define GCC_MAKE_VERSION(major, minor, patchlevel) ((major) * 10000 + (minor) * 100 + patchlevel)
+
+#ifdef __GNUC__
+#define GCC_VERSION GCC_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#else
+#define GCC_VERSION 0
+#endif
+
+#ifdef __clang__
+# define CLANG_VERSION GCC_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+#elif defined(__GNUC__)
+# define CLANG_VERSION 0
+#endif
+
+/**
+ * Are we building with the specified version of gcc (not clang or any
+ * other compiler) or newer?
+ */
+#define GCC_CHECK_VERSION(major, minor) \
+ (CLANG_VERSION == 0 && \
+ GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
+
+/**
+ * Are we building with clang (any version) or at least the specified
+ * gcc version?
+ */
+#define CLANG_OR_GCC_VERSION(major, minor) \
+ (CLANG_VERSION > 0 || GCC_CHECK_VERSION(major, minor))
+
+/**
+ * Are we building with gcc (not clang or any other compiler) and a
+ * version older than the specified one?
+ */
+#define GCC_OLDER_THAN(major, minor) \
+ (GCC_VERSION > 0 && CLANG_VERSION == 0 && \
+ GCC_VERSION < GCC_MAKE_VERSION(major, minor, 0))
+
+#ifdef __clang__
+# if __clang_major__ < 3
+# error Sorry, your clang version is too old. You need at least version 3.1.
+# endif
+#elif defined(__GNUC__)
+# if GCC_OLDER_THAN(6,0)
+# error Sorry, your gcc version is too old. You need at least version 6.0.
+# endif
+#else
+# warning Untested compiler. Use at your own risk!
+#endif
+
+/**
+ * Are we building with the specified version of clang or newer?
+ */
+#define CLANG_CHECK_VERSION(major, minor) \
+ (CLANG_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
+
+#if CLANG_OR_GCC_VERSION(4,0)
+
+/* GCC 4.x */
+
+#define gcc_const __attribute__((const))
+#define gcc_deprecated __attribute__((deprecated))
+#define gcc_may_alias __attribute__((may_alias))
+#define gcc_malloc __attribute__((malloc))
+#define gcc_noreturn __attribute__((noreturn))
+#define gcc_packed __attribute__((packed))
+#define gcc_printf(a,b) __attribute__((format(printf, a, b)))
+#define gcc_pure __attribute__((pure))
+#define gcc_sentinel __attribute__((sentinel))
+#define gcc_unused __attribute__((unused))
+#define gcc_warn_unused_result __attribute__((warn_unused_result))
+
+#define gcc_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
+#define gcc_nonnull_all __attribute__((nonnull))
+#define gcc_returns_nonnull __attribute__((returns_nonnull))
+#define gcc_returns_twice __attribute__((returns_twice))
+
+#define gcc_likely(x) __builtin_expect (!!(x), 1)
+#define gcc_unlikely(x) __builtin_expect (!!(x), 0)
+
+#define gcc_visibility_hidden __attribute__((visibility("hidden")))
+#define gcc_visibility_default __attribute__((visibility("default")))
+
+#define gcc_noinline __attribute__((noinline))
+#define gcc_always_inline __attribute__((always_inline))
+
+#else
+
+/* generic C compiler */
+
+#define gcc_const
+#define gcc_deprecated
+#define gcc_may_alias
+#define gcc_malloc
+#define gcc_noreturn
+#define gcc_packed
+#define gcc_printf(a,b)
+#define gcc_pure
+#define gcc_sentinel
+#define gcc_unused
+#define gcc_warn_unused_result
+
+#define gcc_nonnull(...)
+#define gcc_nonnull_all
+#define gcc_returns_nonnull
+#define gcc_returns_twice
+
+#define gcc_likely(x) (x)
+#define gcc_unlikely(x) (x)
+
+#define gcc_visibility_hidden
+#define gcc_visibility_default
+
+#define gcc_noinline
+#define gcc_always_inline inline
+
+#endif
+
+#if CLANG_OR_GCC_VERSION(4,3)
+
+#define gcc_hot __attribute__((hot))
+#define gcc_cold __attribute__((cold))
+
+#else /* ! GCC_UNUSED >= 40300 */
+
+#define gcc_hot
+#define gcc_cold
+
+#endif /* ! GCC_UNUSED >= 40300 */
+
+#if GCC_CHECK_VERSION(4,6)
+#define gcc_flatten __attribute__((flatten))
+#else
+#define gcc_flatten
+#endif
+
+#ifndef __cplusplus
+/* plain C99 has "restrict" */
+#define gcc_restrict restrict
+#elif CLANG_OR_GCC_VERSION(4,0)
+/* "__restrict__" is a GCC extension for C++ */
+#define gcc_restrict __restrict__
+#else
+/* disable it on other compilers */
+#define gcc_restrict
+#endif
+
+#ifndef __has_feature
+ // define dummy macro for non-clang compilers
+ #define __has_feature(x) 0
+#endif
+
+#if __has_feature(attribute_unused_on_fields)
+#define gcc_unused_field gcc_unused
+#else
+#define gcc_unused_field
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define gcc_unreachable() __builtin_unreachable()
+#else
+#define gcc_unreachable()
+#endif
+
+#endif