From 1dd1a705b58f1645cda679b88a2629d21adcbd07 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 15 Oct 2013 09:13:22 +0200 Subject: gcc.h: major update Copy the according file from another project (i.e. XCSoar). This will allow copying more code more easily. --- src/Client.hxx | 2 +- src/Log.hxx | 16 ++-- src/gcc.h | 196 +++++++++++++++++++++++++++++++----------------- src/pcm/PcmChannels.cxx | 36 ++++----- src/pcm/PcmFormat.cxx | 12 +-- src/protocol/Result.hxx | 2 +- 6 files changed, 163 insertions(+), 101 deletions(-) diff --git a/src/Client.hxx b/src/Client.hxx index 1456f1b7d..36767e9fc 100644 --- a/src/Client.hxx +++ b/src/Client.hxx @@ -72,7 +72,7 @@ void client_vprintf(Client *client, const char *fmt, va_list args); /** * Write a printf-like formatted string to the client. */ -gcc_fprintf +gcc_printf(2,3) void client_printf(Client *client, const char *fmt, ...); diff --git a/src/Log.hxx b/src/Log.hxx index 719f1c448..f7803ceb6 100644 --- a/src/Log.hxx +++ b/src/Log.hxx @@ -43,7 +43,7 @@ enum class LogLevel { void Log(const Domain &domain, LogLevel level, const char *msg); -gcc_fprintf_ +gcc_printf(3,4) void LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...); @@ -53,7 +53,7 @@ LogDebug(const Domain &domain, const char *msg) Log(domain, LogLevel::DEBUG, msg); } -gcc_fprintf +gcc_printf(2,3) void FormatDebug(const Domain &domain, const char *fmt, ...); @@ -63,7 +63,7 @@ LogInfo(const Domain &domain, const char *msg) Log(domain, LogLevel::INFO, msg); } -gcc_fprintf +gcc_printf(2,3) void FormatInfo(const Domain &domain, const char *fmt, ...); @@ -73,7 +73,7 @@ LogWarning(const Domain &domain, const char *msg) Log(domain, LogLevel::WARNING, msg); } -gcc_fprintf +gcc_printf(2,3) void FormatWarning(const Domain &domain, const char *fmt, ...); @@ -83,7 +83,7 @@ LogError(const Domain &domain, const char *msg) Log(domain, LogLevel::ERROR, msg); } -gcc_fprintf +gcc_printf(2,3) void FormatError(const Domain &domain, const char *fmt, ...); @@ -93,7 +93,7 @@ LogError(const Error &error); void LogError(const Error &error, const char *msg); -gcc_fprintf +gcc_printf(2,3) void FormatError(const Error &error, const char *fmt, ...); @@ -103,11 +103,11 @@ LogErrno(const Domain &domain, int e, const char *msg); void LogErrno(const Domain &domain, const char *msg); -gcc_fprintf_ +gcc_printf(3,4) void FormatErrno(const Domain &domain, int e, const char *fmt, ...); -gcc_fprintf +gcc_printf(2,3) void FormatErrno(const Domain &domain, const char *fmt, ...); diff --git a/src/gcc.h b/src/gcc.h index c0796b0fb..2946eae0d 100644 --- a/src/gcc.h +++ b/src/gcc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2011 The Music Player Daemon Project + * Copyright (C) 2003-2013 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,92 +21,154 @@ #define MPD_GCC_H #define GCC_CHECK_VERSION(major, minor) \ - (defined(__GNUC__) && \ - (__GNUC__ > (major) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))) + (defined(__GNUC__) && \ + (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))) -/* this allows us to take advantage of special gcc features while still - * allowing other compilers to compile: - * - * example taken from: http://rlove.org/log/2005102601 - */ +#ifdef __GNUC__ +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) +#else +#define GCC_VERSION 0 +#endif + +#ifdef __clang__ +# define CLANG_VERSION (__clang_major__ * 10000 \ + + __clang_minor__ * 100 \ + + __clang_patchlevel__) +# 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_CHECK_VERSION(4,6) +# error Sorry, your gcc version is too old. You need at least version 4.6. +# endif +#else +# warning Untested compiler. Use at your own risk! +#endif + +#if GCC_CHECK_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_likely(x) __builtin_expect (!!(x), 1) +#define gcc_unlikely(x) __builtin_expect (!!(x), 0) -#if GCC_CHECK_VERSION(3,0) -# define gcc_const __attribute__((const)) -# define gcc_pure __attribute__((pure)) -# define gcc_malloc __attribute__((malloc)) -# define gcc_noreturn __attribute__((noreturn)) -# define gcc_must_check __attribute__ ((warn_unused_result)) -# define gcc_packed __attribute__ ((packed)) -/* these are very useful for type checking */ -# define gcc_printf __attribute__ ((format(printf,1,2))) -# define gcc_fprintf __attribute__ ((format(printf,2,3))) -# define gcc_fprintf_ __attribute__ ((format(printf,3,4))) -# define gcc_fprintf__ __attribute__ ((format(printf,4,5))) -# define gcc_scanf __attribute__ ((format(scanf,1,2))) -# define gcc_used __attribute__ ((used)) -# define gcc_unused __attribute__((unused)) -# define gcc_warn_unused_result __attribute__((warn_unused_result)) -/* # define inline inline __attribute__ ((always_inline)) */ -# define gcc_noinline __attribute__ ((noinline)) -# define gcc_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) -# define gcc_nonnull_all __attribute__((nonnull)) - -# define gcc_likely(x) __builtin_expect (!!(x), 1) -# define gcc_unlikely(x) __builtin_expect (!!(x), 0) +#define gcc_aligned(n) __attribute__((aligned(n))) + +#define gcc_visibility_hidden __attribute__((visibility("hidden"))) +#define gcc_visibility_default __attribute__((visibility("default"))) + +#define gcc_always_inline __attribute__((always_inline)) #else -# define gcc_unused -# define gcc_const -# define gcc_pure -# define gcc_malloc -# define gcc_noreturn -# define gcc_must_check -# define gcc_packed -# define gcc_printf -# define gcc_fprintf -# define gcc_fprintf_ -# define gcc_fprintf__ -# define gcc_scanf -# define gcc_used -# define gcc_unused -# define gcc_warn_unused_result -/* # define inline */ -# define gcc_noinline -# define gcc_nonnull(...) -# define gcc_nonnull_all - -# define gcc_likely(x) (x) -# define gcc_unlikely(x) (x) + +/* 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_likely(x) (x) +#define gcc_unlikely(x) (x) + +#define gcc_aligned(n) + +#define gcc_visibility_hidden +#define gcc_visibility_default + +#define gcc_always_inline inline #endif -#if defined(__GNUC__) || defined(__clang__) -#define gcc_unreachable() __builtin_unreachable() +#if GCC_CHECK_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) && !defined(__clang__) +#define gcc_flatten __attribute__((flatten)) #else -#define gcc_unreachable() +#define gcc_flatten #endif -#ifdef __cplusplus - -#ifdef __GNUC__ +#ifndef __cplusplus +/* plain C99 has "restrict" */ +#define gcc_restrict restrict +#elif GCC_CHECK_VERSION(4,0) /* "__restrict__" is a GCC extension for C++ */ -#define restrict __restrict__ +#define gcc_restrict __restrict__ #else /* disable it on other compilers */ -#define restrict +#define gcc_restrict #endif -#if !defined(__clang__) && defined(__GNUC__) && !GCC_CHECK_VERSION(4,6) -#error Your gcc version is too old. MPD requires gcc 4.6 or newer. -#endif +/* C++11 features */ + +#if defined(__cplusplus) /* support for C++11 "override" was added in gcc 4.7 */ -#if !defined(__clang__) && defined(__GNUC__) && !GCC_CHECK_VERSION(4,7) +#if !defined(__clang__) && !GCC_CHECK_VERSION(4,7) #define override #define final #endif +#if defined(__clang__) || GCC_CHECK_VERSION(4,8) +#define gcc_alignas(T, fallback) alignas(T) +#else +#define gcc_alignas(T, fallback) gcc_aligned(fallback) +#endif + #endif -#endif /* MPD_GCC_H */ +#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 diff --git a/src/pcm/PcmChannels.cxx b/src/pcm/PcmChannels.cxx index 27a155063..a0791078c 100644 --- a/src/pcm/PcmChannels.cxx +++ b/src/pcm/PcmChannels.cxx @@ -38,9 +38,9 @@ MonoToStereo(D dest, S src, S end) } static void -pcm_convert_channels_16_2_to_1(int16_t *restrict dest, - const int16_t *restrict src, - const int16_t *restrict src_end) +pcm_convert_channels_16_2_to_1(int16_t *gcc_restrict dest, + const int16_t *gcc_restrict src, + const int16_t *gcc_restrict src_end) { while (src < src_end) { int32_t a = *src++, b = *src++; @@ -50,10 +50,10 @@ pcm_convert_channels_16_2_to_1(int16_t *restrict dest, } static void -pcm_convert_channels_16_n_to_2(int16_t *restrict dest, +pcm_convert_channels_16_n_to_2(int16_t *gcc_restrict dest, unsigned src_channels, - const int16_t *restrict src, - const int16_t *restrict src_end) + const int16_t *gcc_restrict src, + const int16_t *gcc_restrict src_end) { unsigned c; @@ -101,9 +101,9 @@ pcm_convert_channels_16(PcmBuffer &buffer, } static void -pcm_convert_channels_24_2_to_1(int32_t *restrict dest, - const int32_t *restrict src, - const int32_t *restrict src_end) +pcm_convert_channels_24_2_to_1(int32_t *gcc_restrict dest, + const int32_t *gcc_restrict src, + const int32_t *gcc_restrict src_end) { while (src < src_end) { int32_t a = *src++, b = *src++; @@ -113,10 +113,10 @@ pcm_convert_channels_24_2_to_1(int32_t *restrict dest, } static void -pcm_convert_channels_24_n_to_2(int32_t *restrict dest, +pcm_convert_channels_24_n_to_2(int32_t *gcc_restrict dest, unsigned src_channels, - const int32_t *restrict src, - const int32_t *restrict src_end) + const int32_t *gcc_restrict src, + const int32_t *gcc_restrict src_end) { unsigned c; @@ -165,9 +165,9 @@ pcm_convert_channels_24(PcmBuffer &buffer, } static void -pcm_convert_channels_32_2_to_1(int32_t *restrict dest, - const int32_t *restrict src, - const int32_t *restrict src_end) +pcm_convert_channels_32_2_to_1(int32_t *gcc_restrict dest, + const int32_t *gcc_restrict src, + const int32_t *gcc_restrict src_end) { while (src < src_end) { int64_t a = *src++, b = *src++; @@ -228,9 +228,9 @@ pcm_convert_channels_32(PcmBuffer &buffer, } static void -pcm_convert_channels_float_2_to_1(float *restrict dest, - const float *restrict src, - const float *restrict src_end) +pcm_convert_channels_float_2_to_1(float *gcc_restrict dest, + const float *gcc_restrict src, + const float *gcc_restrict src_end) { while (src < src_end) { double a = *src++, b = *src++; diff --git a/src/pcm/PcmFormat.cxx b/src/pcm/PcmFormat.cxx index 6425c7cfd..b4307ca1f 100644 --- a/src/pcm/PcmFormat.cxx +++ b/src/pcm/PcmFormat.cxx @@ -195,9 +195,9 @@ pcm_convert_16_to_24(int32_t *out, const int16_t *in, const int16_t *in_end) } static void -pcm_convert_32_to_24(int32_t *restrict out, - const int32_t *restrict in, - const int32_t *restrict in_end) +pcm_convert_32_to_24(int32_t *gcc_restrict out, + const int32_t *gcc_restrict in, + const int32_t *gcc_restrict in_end) { while (in < in_end) *out++ = *in++ >> 8; @@ -300,9 +300,9 @@ pcm_convert_16_to_32(int32_t *out, const int16_t *in, const int16_t *in_end) } static void -pcm_convert_24_to_32(int32_t *restrict out, - const int32_t *restrict in, - const int32_t *restrict in_end) +pcm_convert_24_to_32(int32_t *gcc_restrict out, + const int32_t *gcc_restrict in, + const int32_t *gcc_restrict in_end) { while (in < in_end) *out++ = *in++ << 8; diff --git a/src/protocol/Result.hxx b/src/protocol/Result.hxx index 0f953c62b..659e515bb 100644 --- a/src/protocol/Result.hxx +++ b/src/protocol/Result.hxx @@ -38,7 +38,7 @@ void command_error_v(Client *client, enum ack error, const char *fmt, va_list args); -gcc_fprintf_ +gcc_printf(3,4) void command_error(Client *client, enum ack error, const char *fmt, ...); -- cgit v1.2.3