Commit 1dd1a705 authored by Max Kellermann's avatar Max Kellermann

gcc.h: major update

Copy the according file from another project (i.e. XCSoar). This will allow copying more code more easily.
parent e4e80ff0
...@@ -72,7 +72,7 @@ void client_vprintf(Client *client, const char *fmt, va_list args); ...@@ -72,7 +72,7 @@ void client_vprintf(Client *client, const char *fmt, va_list args);
/** /**
* Write a printf-like formatted string to the client. * Write a printf-like formatted string to the client.
*/ */
gcc_fprintf gcc_printf(2,3)
void void
client_printf(Client *client, const char *fmt, ...); client_printf(Client *client, const char *fmt, ...);
......
...@@ -43,7 +43,7 @@ enum class LogLevel { ...@@ -43,7 +43,7 @@ enum class LogLevel {
void void
Log(const Domain &domain, LogLevel level, const char *msg); Log(const Domain &domain, LogLevel level, const char *msg);
gcc_fprintf_ gcc_printf(3,4)
void void
LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...); LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...);
...@@ -53,7 +53,7 @@ LogDebug(const Domain &domain, const char *msg) ...@@ -53,7 +53,7 @@ LogDebug(const Domain &domain, const char *msg)
Log(domain, LogLevel::DEBUG, msg); Log(domain, LogLevel::DEBUG, msg);
} }
gcc_fprintf gcc_printf(2,3)
void void
FormatDebug(const Domain &domain, const char *fmt, ...); FormatDebug(const Domain &domain, const char *fmt, ...);
...@@ -63,7 +63,7 @@ LogInfo(const Domain &domain, const char *msg) ...@@ -63,7 +63,7 @@ LogInfo(const Domain &domain, const char *msg)
Log(domain, LogLevel::INFO, msg); Log(domain, LogLevel::INFO, msg);
} }
gcc_fprintf gcc_printf(2,3)
void void
FormatInfo(const Domain &domain, const char *fmt, ...); FormatInfo(const Domain &domain, const char *fmt, ...);
...@@ -73,7 +73,7 @@ LogWarning(const Domain &domain, const char *msg) ...@@ -73,7 +73,7 @@ LogWarning(const Domain &domain, const char *msg)
Log(domain, LogLevel::WARNING, msg); Log(domain, LogLevel::WARNING, msg);
} }
gcc_fprintf gcc_printf(2,3)
void void
FormatWarning(const Domain &domain, const char *fmt, ...); FormatWarning(const Domain &domain, const char *fmt, ...);
...@@ -83,7 +83,7 @@ LogError(const Domain &domain, const char *msg) ...@@ -83,7 +83,7 @@ LogError(const Domain &domain, const char *msg)
Log(domain, LogLevel::ERROR, msg); Log(domain, LogLevel::ERROR, msg);
} }
gcc_fprintf gcc_printf(2,3)
void void
FormatError(const Domain &domain, const char *fmt, ...); FormatError(const Domain &domain, const char *fmt, ...);
...@@ -93,7 +93,7 @@ LogError(const Error &error); ...@@ -93,7 +93,7 @@ LogError(const Error &error);
void void
LogError(const Error &error, const char *msg); LogError(const Error &error, const char *msg);
gcc_fprintf gcc_printf(2,3)
void void
FormatError(const Error &error, const char *fmt, ...); FormatError(const Error &error, const char *fmt, ...);
...@@ -103,11 +103,11 @@ LogErrno(const Domain &domain, int e, const char *msg); ...@@ -103,11 +103,11 @@ LogErrno(const Domain &domain, int e, const char *msg);
void void
LogErrno(const Domain &domain, const char *msg); LogErrno(const Domain &domain, const char *msg);
gcc_fprintf_ gcc_printf(3,4)
void void
FormatErrno(const Domain &domain, int e, const char *fmt, ...); FormatErrno(const Domain &domain, int e, const char *fmt, ...);
gcc_fprintf gcc_printf(2,3)
void void
FormatErrno(const Domain &domain, const char *fmt, ...); FormatErrno(const Domain &domain, const char *fmt, ...);
......
/* /*
* Copyright (C) 2003-2011 The Music Player Daemon Project * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -21,92 +21,154 @@ ...@@ -21,92 +21,154 @@
#define MPD_GCC_H #define MPD_GCC_H
#define GCC_CHECK_VERSION(major, minor) \ #define GCC_CHECK_VERSION(major, minor) \
(defined(__GNUC__) && \ (defined(__GNUC__) && \
(__GNUC__ > (major) || \ (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
(__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
/* this allows us to take advantage of special gcc features while still #ifdef __GNUC__
* allowing other compilers to compile: #define GCC_VERSION (__GNUC__ * 10000 \
* + __GNUC_MINOR__ * 100 \
* example taken from: http://rlove.org/log/2005102601 + __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_aligned(n) __attribute__((aligned(n)))
# define gcc_const __attribute__((const))
# define gcc_pure __attribute__((pure)) #define gcc_visibility_hidden __attribute__((visibility("hidden")))
# define gcc_malloc __attribute__((malloc)) #define gcc_visibility_default __attribute__((visibility("default")))
# define gcc_noreturn __attribute__((noreturn))
# define gcc_must_check __attribute__ ((warn_unused_result)) #define gcc_always_inline __attribute__((always_inline))
# 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)
#else #else
# define gcc_unused
# define gcc_const /* generic C compiler */
# define gcc_pure
# define gcc_malloc #define gcc_const
# define gcc_noreturn #define gcc_deprecated
# define gcc_must_check #define gcc_may_alias
# define gcc_packed #define gcc_malloc
# define gcc_printf #define gcc_noreturn
# define gcc_fprintf #define gcc_packed
# define gcc_fprintf_ #define gcc_printf(a,b)
# define gcc_fprintf__ #define gcc_pure
# define gcc_scanf #define gcc_sentinel
# define gcc_used #define gcc_unused
# define gcc_unused #define gcc_warn_unused_result
# define gcc_warn_unused_result
/* # define inline */ #define gcc_nonnull(...)
# define gcc_noinline #define gcc_nonnull_all
# define gcc_nonnull(...)
# define gcc_nonnull_all #define gcc_likely(x) (x)
#define gcc_unlikely(x) (x)
# 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 #endif
#if defined(__GNUC__) || defined(__clang__) #if GCC_CHECK_VERSION(4,3)
#define gcc_unreachable() __builtin_unreachable()
#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 #else
#define gcc_unreachable() #define gcc_flatten
#endif #endif
#ifdef __cplusplus #ifndef __cplusplus
/* plain C99 has "restrict" */
#ifdef __GNUC__ #define gcc_restrict restrict
#elif GCC_CHECK_VERSION(4,0)
/* "__restrict__" is a GCC extension for C++ */ /* "__restrict__" is a GCC extension for C++ */
#define restrict __restrict__ #define gcc_restrict __restrict__
#else #else
/* disable it on other compilers */ /* disable it on other compilers */
#define restrict #define gcc_restrict
#endif #endif
#if !defined(__clang__) && defined(__GNUC__) && !GCC_CHECK_VERSION(4,6) /* C++11 features */
#error Your gcc version is too old. MPD requires gcc 4.6 or newer.
#endif #if defined(__cplusplus)
/* support for C++11 "override" was added in gcc 4.7 */ /* 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 override
#define final #define final
#endif #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
#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
...@@ -38,9 +38,9 @@ MonoToStereo(D dest, S src, S end) ...@@ -38,9 +38,9 @@ MonoToStereo(D dest, S src, S end)
} }
static void static void
pcm_convert_channels_16_2_to_1(int16_t *restrict dest, pcm_convert_channels_16_2_to_1(int16_t *gcc_restrict dest,
const int16_t *restrict src, const int16_t *gcc_restrict src,
const int16_t *restrict src_end) const int16_t *gcc_restrict src_end)
{ {
while (src < src_end) { while (src < src_end) {
int32_t a = *src++, b = *src++; int32_t a = *src++, b = *src++;
...@@ -50,10 +50,10 @@ pcm_convert_channels_16_2_to_1(int16_t *restrict dest, ...@@ -50,10 +50,10 @@ pcm_convert_channels_16_2_to_1(int16_t *restrict dest,
} }
static void 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, unsigned src_channels,
const int16_t *restrict src, const int16_t *gcc_restrict src,
const int16_t *restrict src_end) const int16_t *gcc_restrict src_end)
{ {
unsigned c; unsigned c;
...@@ -101,9 +101,9 @@ pcm_convert_channels_16(PcmBuffer &buffer, ...@@ -101,9 +101,9 @@ pcm_convert_channels_16(PcmBuffer &buffer,
} }
static void static void
pcm_convert_channels_24_2_to_1(int32_t *restrict dest, pcm_convert_channels_24_2_to_1(int32_t *gcc_restrict dest,
const int32_t *restrict src, const int32_t *gcc_restrict src,
const int32_t *restrict src_end) const int32_t *gcc_restrict src_end)
{ {
while (src < src_end) { while (src < src_end) {
int32_t a = *src++, b = *src++; int32_t a = *src++, b = *src++;
...@@ -113,10 +113,10 @@ pcm_convert_channels_24_2_to_1(int32_t *restrict dest, ...@@ -113,10 +113,10 @@ pcm_convert_channels_24_2_to_1(int32_t *restrict dest,
} }
static void 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, unsigned src_channels,
const int32_t *restrict src, const int32_t *gcc_restrict src,
const int32_t *restrict src_end) const int32_t *gcc_restrict src_end)
{ {
unsigned c; unsigned c;
...@@ -165,9 +165,9 @@ pcm_convert_channels_24(PcmBuffer &buffer, ...@@ -165,9 +165,9 @@ pcm_convert_channels_24(PcmBuffer &buffer,
} }
static void static void
pcm_convert_channels_32_2_to_1(int32_t *restrict dest, pcm_convert_channels_32_2_to_1(int32_t *gcc_restrict dest,
const int32_t *restrict src, const int32_t *gcc_restrict src,
const int32_t *restrict src_end) const int32_t *gcc_restrict src_end)
{ {
while (src < src_end) { while (src < src_end) {
int64_t a = *src++, b = *src++; int64_t a = *src++, b = *src++;
...@@ -228,9 +228,9 @@ pcm_convert_channels_32(PcmBuffer &buffer, ...@@ -228,9 +228,9 @@ pcm_convert_channels_32(PcmBuffer &buffer,
} }
static void static void
pcm_convert_channels_float_2_to_1(float *restrict dest, pcm_convert_channels_float_2_to_1(float *gcc_restrict dest,
const float *restrict src, const float *gcc_restrict src,
const float *restrict src_end) const float *gcc_restrict src_end)
{ {
while (src < src_end) { while (src < src_end) {
double a = *src++, b = *src++; double a = *src++, b = *src++;
......
...@@ -195,9 +195,9 @@ pcm_convert_16_to_24(int32_t *out, const int16_t *in, const int16_t *in_end) ...@@ -195,9 +195,9 @@ pcm_convert_16_to_24(int32_t *out, const int16_t *in, const int16_t *in_end)
} }
static void static void
pcm_convert_32_to_24(int32_t *restrict out, pcm_convert_32_to_24(int32_t *gcc_restrict out,
const int32_t *restrict in, const int32_t *gcc_restrict in,
const int32_t *restrict in_end) const int32_t *gcc_restrict in_end)
{ {
while (in < in_end) while (in < in_end)
*out++ = *in++ >> 8; *out++ = *in++ >> 8;
...@@ -300,9 +300,9 @@ pcm_convert_16_to_32(int32_t *out, const int16_t *in, const int16_t *in_end) ...@@ -300,9 +300,9 @@ pcm_convert_16_to_32(int32_t *out, const int16_t *in, const int16_t *in_end)
} }
static void static void
pcm_convert_24_to_32(int32_t *restrict out, pcm_convert_24_to_32(int32_t *gcc_restrict out,
const int32_t *restrict in, const int32_t *gcc_restrict in,
const int32_t *restrict in_end) const int32_t *gcc_restrict in_end)
{ {
while (in < in_end) while (in < in_end)
*out++ = *in++ << 8; *out++ = *in++ << 8;
......
...@@ -38,7 +38,7 @@ void ...@@ -38,7 +38,7 @@ void
command_error_v(Client *client, enum ack error, command_error_v(Client *client, enum ack error,
const char *fmt, va_list args); const char *fmt, va_list args);
gcc_fprintf_ gcc_printf(3,4)
void void
command_error(Client *client, enum ack error, const char *fmt, ...); command_error(Client *client, enum ack error, const char *fmt, ...);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment