Commit | Line | Data |
---|---|---|
a8909ba5 | 1 | /* |
c0c0989a | 2 | * SPDX-License-Identifier: MIT |
a8909ba5 | 3 | * |
c0c0989a MJ |
4 | * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
5 | * Copyright (C) 2011-2012 Paul Woegerer <paul_woegerer@mentor.com> | |
a8909ba5 PW |
6 | */ |
7 | ||
c0c0989a MJ |
8 | #ifndef _LTTNG_UST_COMPILER_H |
9 | #define _LTTNG_UST_COMPILER_H | |
10 | ||
7f264068 FD |
11 | #include <assert.h> |
12 | ||
a8909ba5 | 13 | #define lttng_ust_notrace __attribute__((no_instrument_function)) |
b3f60bbf | 14 | #define LTTNG_PACKED __attribute__((__packed__)) |
a8909ba5 | 15 | |
4f74bc5e MD |
16 | /* |
17 | * Clang supports the no_sanitize variable attribute on global variables. | |
18 | * GCC only supports the no_sanitize_address function attribute, which is | |
19 | * not what we need. | |
20 | */ | |
21 | #if defined(__clang__) | |
22 | # if __has_feature(address_sanitizer) | |
23 | # define __lttng_ust_variable_attribute_no_sanitize_address \ | |
24 | __attribute__((no_sanitize("address"))) | |
25 | # else | |
26 | # define __lttng_ust_variable_attribute_no_sanitize_address | |
27 | # endif | |
28 | #else | |
29 | # define __lttng_ust_variable_attribute_no_sanitize_address | |
30 | #endif | |
31 | ||
e1904921 MD |
32 | /* |
33 | * g++ 4.8 and prior do not support C99 compound literals. Therefore, | |
34 | * force allocating those on the heap with these C++ compilers. | |
35 | */ | |
36 | #if defined (__cplusplus) && defined (__GNUC__) && \ | |
37 | (__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 8)) | |
38 | # ifndef LTTNG_ALLOCATE_COMPOUND_LITERAL_ON_HEAP | |
39 | # define LTTNG_ALLOCATE_COMPOUND_LITERAL_ON_HEAP | |
40 | # endif | |
41 | #endif | |
42 | ||
7edfc172 MD |
43 | /* |
44 | * Compound literals with static storage are needed by LTTng. | |
45 | * Compound literals are part of the C99 and C11 standards, but not | |
46 | * part of the C++ standards. However, those are supported by both g++ and | |
47 | * clang. In order to be strictly C++11 compliant, defining | |
48 | * LTTNG_ALLOCATE_COMPOUND_LITERAL_ON_HEAP before including this header | |
49 | * allocates those on the heap in C++. | |
50 | * | |
51 | * Example use: | |
52 | * static struct mystruct *var = __LTTNG_COMPOUND_LITERAL(struct mystruct, { 1, 2, 3 }); | |
53 | */ | |
54 | #if defined (__cplusplus) && defined (LTTNG_ALLOCATE_COMPOUND_LITERAL_ON_HEAP) | |
55 | #define __LTTNG_COMPOUND_LITERAL(type, ...) new (type) __VA_ARGS__ | |
56 | #else | |
57 | #define __LTTNG_COMPOUND_LITERAL(type, ...) (type[]) { __VA_ARGS__ } | |
58 | #endif | |
59 | ||
7f264068 FD |
60 | /* |
61 | * Compile time assertion. | |
62 | * - predicate: boolean expression to evaluate, | |
63 | * - msg: string to print to the user on failure when `static_assert()` is | |
64 | * supported, | |
65 | * - c_identifier_msg: message to be included in the typedef to emulate a | |
66 | * static assertion. This parameter must be a valid C identifier as it will | |
67 | * be used as a typedef name. | |
68 | */ | |
69 | #if defined (__cplusplus) || __STDC_VERSION__ >= 201112L | |
70 | #define lttng_static_assert(predicate, msg, c_identifier_msg) \ | |
71 | static_assert(predicate, msg) | |
72 | #else | |
73 | /* | |
74 | * Evaluates the predicate and emit a compilation error on failure. | |
75 | * | |
76 | * If the predicate evaluates to true, this macro emits a typedef of an array | |
77 | * of size 0. | |
78 | * | |
79 | * If the predicate evaluates to false, this macro emits a typedef of an array | |
80 | * of negative size which is invalid in C and forces a compiler error. The msg | |
81 | * parameter is used in the tentative typedef so it is printed to the user. | |
82 | */ | |
83 | #define lttng_static_assert(predicate, msg, c_identifier_msg) \ | |
84 | typedef char lttng_static_assert_##c_identifier_msg[2*!!(predicate)-1]; | |
85 | #endif | |
86 | ||
a8909ba5 | 87 | #endif /* _LTTNG_UST_COMPILER_H */ |