Add C native types macro helpers
authorOlivier Dion <odion@efficios.com>
Tue, 6 Aug 2024 21:09:48 +0000 (17:09 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 23 Oct 2024 15:28:05 +0000 (11:28 -0400)
The SIDE ABI specifies fixed sizes integers and floating points.
However, as a convenience for C/C++, the SIDE C API supports C native
types (e.g. char) which are translated to their equivalent.

Note that the translation of C native types is toolchain dependent and
therefore could produce different results.

The main use case is for auto-generating SIDE events for public API of
shared libraries.

Change-Id: I845f0dd42ba2dc2de1f540f751e9cd65aa4a8c98
Signed-off-by: Olivier Dion <odion@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/side/instrumentation-c-api.h
tests/unit/c-native-types.h [new file with mode: 0644]
tests/unit/test.c

index 1a9bf842aca56dff41ff22b48bc34dc865072176..f57a44a2d8bf36f17213aea38456d0e2218aa4a3 100644 (file)
 #define side_field_string32(_name, _attr...)           _side_field(_name, side_type_string32(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())))
 #define side_field_dynamic(_name)                      _side_field(_name, side_type_dynamic())
 
+/* C native types. */
+
+/*
+ * The SIDE ABI specifies fixed sizes integers and floating points.  However, as
+ * a convenience for C/C++, the SIDE C API supports C native types (e.g. char)
+ * which are translated to their equivalent.
+ *
+ * Note that the translation of C * native types is toolchain dependent and
+ * therefore could produce different * results.
+ *
+ * The main use case is for auto-generating SIDE events for public API of shared
+ * libraries.
+ */
+
+#ifdef __CHAR_UNSIGNED__
+#  define side_field_char(_name, _attr...) side_field_uchar(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_char(_args...) side_arg_uchar(_args)
+#else
+#  define side_field_char(_name, _attr...) side_field_schar(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_char(_args...) side_arg_schar(_args)
+#endif
+
+#define side_field_schar(_name, _attr...) side_field_s8(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#define side_arg_schar(_args...) side_arg_s8(_args)
+
+#define side_field_uchar(_name, _attr...) side_field_u8(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#define side_arg_uchar(_args...) side_arg_u8(_args)
+
+#if __SIZEOF_SHORT__ <= 2
+#  define side_field_short(_name, _attr...) side_field_s16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_short(_args...) side_arg_s16(_args)
+#  define side_field_ushort(_name, _attr...) side_field_u16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_ushort(_args...) side_arg_u16(_args)
+#elif __SIZEOF_SHORT__ <= 4
+#  define side_field_short(_name, _attr...) side_field_s32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_short(_args...) side_arg_s32(_args)
+#  define side_field_ushort(_name, _attr...) side_field_u32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_ushort(_args...) side_arg_u32(_args)
+#elif __SIZEOF_SHORT__ <= 8
+#  define side_field_short(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_short(_args...) side_arg_s64(_args)
+#  define side_field_ushort(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_ushort(_args...) side_arg_u64(_args)
+#else
+#  define side_field_short(...)                                        \
+       side_static_assert(0, "Type `signed short int' is not supported", type__signed_short_int__is_not_supported)
+#  define side_arg_short(...)                                  \
+       side_static_assert(0, "Type `signed short int' is not supported", type__signed_short_int__is_not_supported)
+#  define side_field_ushort(...)                                       \
+       side_static_assert(0, "Type `unsigned short int' is not supported", type__unsigned_short_int__is_not_supported)
+#  define side_arg_ushort(...)                                         \
+       side_static_assert(0, "Type `unsigned short int' is not supported", type__unsigned_short_int__is_not_supported)
+#endif
+
+#if __SIZEOF_INT__ <= 2
+#  define side_field_int(_name, _attr...) side_field_s16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_int(_args...) side_arg_s16(_args)
+#  define side_field_uint(_name, _attr...) side_field_u16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_uint(_args...) side_arg_u16(_args)
+#elif __SIZEOF_INT__ <= 4
+#  define side_field_int(_name, _attr...) side_field_s32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_int(_args...) side_arg_s32(_args)
+#  define side_field_uint(_name, _attr...) side_field_u32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_uint(_args...) side_arg_u32(_args)
+#elif __SIZEOF_INT__ <= 8
+#  define side_field_int(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_int(_args...) side_arg_s64(_args)
+#  define side_field_uint(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_uint(_args...) side_arg_u64(_args)
+#else
+#  define side_field_int(...)                                          \
+       side_static_assert(0, "Type `signed int' is not supported", type__signed_int__is_not_supported)
+#  define side_arg_int(...)                                            \
+       side_static_assert(0, "Type `signed int' is not supported", type__signed_int__is_not_supported)
+#  define side_field_uint(...)                                         \
+       side_static_assert(0, "Type `unsigned int' is not supported", type__unsigned_int__is_not_supported)
+#  define side_arg_uint(...)                                           \
+       side_static_assert(0, "Type `unsigned int' is not supported", type__unsigned_int__is_not_supported)
+#endif
+
+#if __SIZEOF_LONG__ <= 4
+#  define side_field_long(_name, _attr...) side_field_s32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_long(_args...) side_arg_s32(_args)
+#  define side_field_ulong(_name, _attr...) side_field_u32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_ulong(_args...) side_arg_u32(_args)
+#elif __SIZEOF_LONG__ <= 8
+#  define side_field_long(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_long(_args...) side_arg_s64(_args)
+#  define side_field_ulong(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_ulong(_args...) side_arg_u64(_args)
+#else
+#  define side_field_long(...)                                         \
+       side_static_assert(0, "Type `signed long int' is not supported", type__signed_long_int__is_not_supported)
+#  define side_arg_long(...)                                   \
+       side_static_assert(0, "Type `signed long int' is not supported", type__signed_long_int__is_not_supported)
+#  define side_field_ulong(...)                                        \
+       side_static_assert(0, "Type `unsigned long int' is not supported", type__unsigned_long_int__is_not_supported)
+#  define side_arg_ulong(...)                                          \
+       side_static_assert(0, "Type `unsigned long int' is not supported", type__unsigned_long_int__is_not_supported)
+#endif
+
+#if __SIZEOF_LONG_LONG__ <= 8
+#  define side_field_long_long(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_long_long(_args...) side_arg_s64(_args)
+#  define side_field_ulong_long(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_ulong_long(_args...) side_arg_u64(_args)
+#else
+#  define side_field_long_long(...)                                    \
+       side_static_assert(0, "Type `signed long long int' is not supported", type__signed_long_long_int__is_not_supported)
+#  define side_arg_long_long(...)                                      \
+       side_static_assert(0, "Type `signed long long int' is not supported", type__signed_long_long_int__is_not_supported)
+#  define side_field_long_long(...)                                    \
+       side_static_assert(0, "Type `unsigned long long int' is not supported", type__unsigned_long_long_int__is_not_supported)
+#  define side_arg_long_long(...)                                      \
+       side_static_assert(0, "Type `unsigned long long int' is not supported", type__unsigned_long_long_int__is_not_supported)
+#endif
+
+#if __SIZEOF_FLOAT__ <= 4 && __HAVE_FLOAT32
+#  define side_field_float(_name, _attr...) side_field_float_binary32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_float(_args...) side_arg_float_binary32(_args)
+#elif __SIZEOF_FLOAT__ <= 8 && __HAVE_FLOAT64
+#  define side_field_float(_name, _attr...) side_field_float_binary64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_float(_args...) side_arg_float_binary64(_args)
+#elif __SIZEOF_FLOAT__ <= 16 && __HAVE_FLOAT128
+#  define side_field_float(_name, _attr...) side_field_float_binary128(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_float(_args...) side_arg_float_binary128(_args)
+#else
+#  define side_field_float(...)                                        \
+       side_static_assert(0, "Type `float' is not supported", type__float__is_not_supported)
+#  define side_arg_float(...)                                  \
+       side_static_assert(0, "Type `float' is not supported", type__float__is_not_supported)
+#endif
+
+#if __SIZEOF_DOUBLE__ <= 4 && __HAVE_FLOAT32
+#  define side_field_double(_name, _attr...) side_field_float_binary32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_double(_args...) side_arg_float_binary32(_args)
+#elif __SIZEOF_DOUBLE__ <= 8 && __HAVE_FLOAT64
+#  define side_field_double(_name, _attr...) side_field_float_binary64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_double(_args...) side_arg_float_binary64(_args)
+#elif __SIZEOF_DOUBLE__ <= 16 && __HAVE_FLOAT128
+#  define side_field_double(_name, _attr...) side_field_double_binary128(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#  define side_arg_double(_args...) side_arg_float_binary128(_args)
+#else
+#  define side_field_double(...)                                       \
+       side_static_assert(0, "Type `double' is not supported", type__double__is_not_supported)
+#  define side_arg_double(...)                                 \
+       side_static_assert(0, "Type `double' is not supported", type__double__is_not_supported)
+#endif
+
+#ifdef __SIZEOF_LONG_DOUBLE__
+#  if __SIZEOF_LONG_DOUBLE__ <= 4 && __HAVE_FLOAT32
+#    define side_field_long_double(_name, _attr...) side_field_float_binary32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#    define side_arg_long_double(_args...) side_arg_float_binary32(_args)
+#  elif __SIZEOF_LONG_DOUBLE__ <= 8 && __HAVE_FLOAT64
+#    define side_field_long_double(_name, _attr...) side_field_float_binary64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#    define side_arg_long_double(_args...) side_arg_float_binary64(_args)
+#  elif __SIZEOF_LONG_DOUBLE__ <= 16 && __HAVE_FLOAT128
+#    define side_field_long_double(_name, _attr...) side_field_float_binary128(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
+#    define side_arg_long_double(_args...) side_arg_float_binary128(_args)
+#  else
+#    define side_field_long_double(...)                                        \
+       side_static_assert(0, "Type `long double' is not supported", type__long_double__is_not_supported)
+#    define side_arg_long_double(...)                                  \
+       side_static_assert(0, "Type `long double' is not supported", type__long_double__is_not_supported)
+#  endif
+#endif /* __SIZEOF_LONG_DOUBLE__ */
+
 /* Little endian */
 #define side_type_u16_le(_attr...)                     _side_type_integer(SIDE_TYPE_U16, false, SIDE_TYPE_BYTE_ORDER_LE, sizeof(uint16_t), 0, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
 #define side_type_u32_le(_attr...)                     _side_type_integer(SIDE_TYPE_U32, false, SIDE_TYPE_BYTE_ORDER_LE, sizeof(uint32_t), 0, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))
diff --git a/tests/unit/c-native-types.h b/tests/unit/c-native-types.h
new file mode 100644 (file)
index 0000000..ad03e2c
--- /dev/null
@@ -0,0 +1,23 @@
+#include <float.h>
+#include <limits.h>
+
+/*
+ * Define X before including this file to expand to something.
+ */
+X(char, CHAR_MAX, char);
+X(signed char, SCHAR_MIN, schar);
+X(unsigned char, UCHAR_MAX, uchar);
+X(short, SHRT_MIN, short);
+X(unsigned short, USHRT_MAX, ushort);
+X(int, INT_MIN, int);
+X(unsigned int, UINT_MAX, uint);
+X(long, LONG_MIN, long);
+X(unsigned long, ULONG_MAX, ulong);
+X(long long, LLONG_MIN, long_long);
+X(unsigned long long, ULLONG_MAX, ulong_long);
+X(float, FLT_MIN, float);
+X(double, DBL_MIN, double);
+
+#ifdef __SIZEOF_LONG_DOUBLE__
+X(long double, LDBL_MIN, long_double);
+#endif
index e563d07bff99de7d27fa2ce96b4a6ce5a33c6eac..493d6e5dc4e375c6236c64e31246bbec0c73ed06 100644 (file)
@@ -2262,6 +2262,33 @@ void test_integer128(void)
 #endif
 
 
+#define X(_type, _value, _field)                                       \
+       side_static_event(c_native_types_ ## _field, "c-native-types", #_type, SIDE_LOGLEVEL_DEBUG, \
+                       side_field_list(                                \
+                               side_field_##_field("x"),               \
+                       )                                               \
+               )
+#include "c-native-types.h"
+#undef X
+
+static
+void test_c_native_types(void)
+{
+
+#define X(_type, _value, _field)                               \
+       ({                                                      \
+               _type x = _value;                               \
+               side_event(c_native_types_ ## _field,           \
+                       side_arg_list(                          \
+                               side_arg_##_field(x),           \
+                       )                                       \
+               );                                              \
+       })
+#include "c-native-types.h"
+#undef X
+}
+
+
 int main()
 {
        test_fields();
@@ -2315,5 +2342,6 @@ int main()
        test_string_utf();
        test_variant();
        test_integer128();
+       test_c_native_types();
        return 0;
 }
This page took 0.026602 seconds and 4 git commands to generate.