|
@@ -114,5 +114,44 @@
|
|
#ifndef __has_feature
|
|
#ifndef __has_feature
|
|
#define __has_feature(x) 0 /* compatibility with non-clang compilers */
|
|
#define __has_feature(x) 0 /* compatibility with non-clang compilers */
|
|
#endif
|
|
#endif
|
|
|
|
+/* Implement C11 _Generic via GCC builtins. Example:
|
|
|
|
+ *
|
|
|
|
+ * QEMU_GENERIC(x, (float, sinf), (long double, sinl), sin) (x)
|
|
|
|
+ *
|
|
|
|
+ * The first argument is the discriminator. The last is the default value.
|
|
|
|
+ * The middle ones are tuples in "(type, expansion)" format.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+/* First, find out the number of generic cases. */
|
|
|
|
+#define QEMU_GENERIC(x, ...) \
|
|
|
|
+ QEMU_GENERIC_(typeof(x), __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
|
|
|
+
|
|
|
|
+/* There will be extra arguments, but they are not used. */
|
|
|
|
+#define QEMU_GENERIC_(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, count, ...) \
|
|
|
|
+ QEMU_GENERIC##count(x, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
|
|
|
+
|
|
|
|
+/* Two more helper macros, this time to extract items from a parenthesized
|
|
|
|
+ * list.
|
|
|
|
+ */
|
|
|
|
+#define QEMU_FIRST_(a, b) a
|
|
|
|
+#define QEMU_SECOND_(a, b) b
|
|
|
|
+
|
|
|
|
+/* ... and a final one for the common part of the "recursion". */
|
|
|
|
+#define QEMU_GENERIC_IF(x, type_then, else_) \
|
|
|
|
+ __builtin_choose_expr(__builtin_types_compatible_p(x, \
|
|
|
|
+ QEMU_FIRST_ type_then), \
|
|
|
|
+ QEMU_SECOND_ type_then, else_)
|
|
|
|
+
|
|
|
|
+/* CPP poor man's "recursion". */
|
|
|
|
+#define QEMU_GENERIC1(x, a0, ...) (a0)
|
|
|
|
+#define QEMU_GENERIC2(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC1(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC3(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC2(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC4(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC3(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC5(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC4(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC6(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC5(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC7(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC6(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC8(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC7(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC9(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC8(x, __VA_ARGS__))
|
|
|
|
+#define QEMU_GENERIC10(x, a0, ...) QEMU_GENERIC_IF(x, a0, QEMU_GENERIC9(x, __VA_ARGS__))
|
|
|
|
|
|
#endif /* COMPILER_H */
|
|
#endif /* COMPILER_H */
|