summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Client.hxx2
-rw-r--r--src/Log.hxx16
-rw-r--r--src/gcc.h196
-rw-r--r--src/pcm/PcmChannels.cxx36
-rw-r--r--src/pcm/PcmFormat.cxx12
-rw-r--r--src/protocol/Result.hxx2
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, ...);