Merge branch 'rwonce/rework' of git://git.kernel.org/pub/scm/linux/kernel/git/will...
[linux-2.6-microblaze.git] / include / linux / compiler_types.h
index 6fcf732..d4e1956 100644 (file)
@@ -218,6 +218,53 @@ struct ftrace_likely_data {
 /* Are two types/vars the same type (ignoring qualifiers)? */
 #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
+/*
+ * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
+ *                            non-scalar types unchanged.
+ */
+#if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 40900) || defined(__CHECKER__)
+/*
+ * We build this out of a couple of helper macros in a vain attempt to
+ * help you keep your lunch down while reading it.
+ */
+#define __pick_scalar_type(x, type, otherwise)                                 \
+       __builtin_choose_expr(__same_type(x, type), (type)0, otherwise)
+
+/*
+ * 'char' is not type-compatible with either 'signed char' or 'unsigned char',
+ * so we include the naked type here as well as the signed/unsigned variants.
+ */
+#define __pick_integer_type(x, type, otherwise)                                        \
+       __pick_scalar_type(x, type,                                             \
+               __pick_scalar_type(x, unsigned type,                            \
+                       __pick_scalar_type(x, signed type, otherwise)))
+
+#define __unqual_scalar_typeof(x) typeof(                                      \
+       __pick_integer_type(x, char,                                            \
+               __pick_integer_type(x, short,                                   \
+                       __pick_integer_type(x, int,                             \
+                               __pick_integer_type(x, long,                    \
+                                       __pick_integer_type(x, long long, x))))))
+#else
+/*
+ * If supported, prefer C11 _Generic for better compile-times. As above, 'char'
+ * is not type-compatible with 'signed char', and we define a separate case.
+ */
+#define __scalar_type_to_expr_cases(type)                              \
+               unsigned type:  (unsigned type)0,                       \
+               signed type:    (signed type)0
+
+#define __unqual_scalar_typeof(x) typeof(                              \
+               _Generic((x),                                           \
+                        char:  (char)0,                                \
+                        __scalar_type_to_expr_cases(char),             \
+                        __scalar_type_to_expr_cases(short),            \
+                        __scalar_type_to_expr_cases(int),              \
+                        __scalar_type_to_expr_cases(long),             \
+                        __scalar_type_to_expr_cases(long long),        \
+                        default: (x)))
+#endif
+
 /* Is this type a native word size -- useful for atomic operations */
 #define __native_word(t) \
        (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \