From 5c8f880a6c5755fe26f8275e63696e42f49bdae0 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 13 May 2013 21:46:07 +0000 Subject: Rework the way C11 keywords are defined. Instead of only checking the __STDC_VERSION__, we can also use Clang's __has_extension() to check for features specifically. This allows us to, say, use Clang's native _Static_assert() instead of the typedef hack, making the compiler error messages a lot more readable. Reviewed by: theraven --- sys/sys/cdefs.h | 82 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h index ad6aefc..7280fe1 100644 --- a/sys/sys/cdefs.h +++ b/sys/sys/cdefs.h @@ -36,6 +36,23 @@ #ifndef _SYS_CDEFS_H_ #define _SYS_CDEFS_H_ +/* + * Testing against Clang-specific extensions. + */ + +#ifndef __has_extension +#define __has_extension __has_feature +#endif +#ifndef __has_feature +#define __has_feature(x) 0 +#endif +#ifndef __has_include +#define __has_include(x) 0 +#endif +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + #if defined(__cplusplus) #define __BEGIN_DECLS extern "C" { #define __END_DECLS } @@ -232,22 +249,36 @@ /* * Keywords added in C11. */ -#if defined(__cplusplus) && __cplusplus >= 201103L -#define _Alignas(e) alignas(e) -#define _Alignof(e) alignof(e) -#define _Noreturn [[noreturn]] -#define _Static_assert(e, s) static_assert(e, s) -/* FIXME: change this to thread_local when clang in base supports it */ -#define _Thread_local __thread -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -/* Do nothing. They are language keywords. */ + +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L + +#if !__has_extension(c_alignas) +#if (defined(__cplusplus) && __cplusplus >= 201103L) || \ + __has_extension(cxx_alignas) +#define _Alignas(x) alignas(x) #else -/* Not supported. Implement them using our versions. */ +/* XXX: Only emulates _Alignas(constant-expression); not _Alignas(type-name). */ #define _Alignas(x) __aligned(x) +#endif +#endif + +#if defined(__cplusplus) && __cplusplus >= 201103L +#define _Alignof(x) alignof(x) +#else #define _Alignof(x) __alignof(x) +#endif + +#if defined(__cplusplus) && __cplusplus >= 201103L +#define _Noreturn [[noreturn]] +#else #define _Noreturn __dead2 -#define _Thread_local __thread -#ifdef __COUNTER__ +#endif + +#if !__has_extension(c_static_assert) +#if (defined(__cplusplus) && __cplusplus >= 201103L) || \ + __has_extension(cxx_static_assert) +#define _Static_assert(x, y) static_assert(x, y) +#elif defined(__COUNTER__) #define _Static_assert(x, y) __Static_assert(x, __COUNTER__) #define __Static_assert(x, y) ___Static_assert(x, y) #define ___Static_assert(x, y) typedef char __assert_ ## y[(x) ? 1 : -1] @@ -256,6 +287,20 @@ #endif #endif +#if !__has_extension(c_thread_local) +/* XXX: Change this to test against C++11 when clang in base supports it. */ +#if /* (defined(__cplusplus) && __cplusplus >= 201103L) || */ \ + __has_extension(cxx_thread_local) +#define _Thread_local thread_local +#elif defined(lint) +#define _Thread_local +#else +#define _Thread_local __thread +#endif +#endif + +#endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */ + /* * Emulation of C11 _Generic(). Unlike the previously defined C11 * keywords, it is not possible to implement this using exactly the same @@ -682,19 +727,6 @@ #endif #endif -#ifndef __has_extension -#define __has_extension __has_feature -#endif -#ifndef __has_feature -#define __has_feature(x) 0 -#endif -#ifndef __has_include -#define __has_include(x) 0 -#endif -#ifndef __has_builtin -#define __has_builtin(x) 0 -#endif - #if defined(__mips) || defined(__powerpc64__) #define __NO_TLS 1 #endif -- cgit v1.1