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 | ||
63661b66 MD |
13 | /* |
14 | * By default, LTTng-UST uses the priority 150 for the tracepoint and probe | |
15 | * provider constructors to trace tracepoints located within | |
16 | * constructors/destructors with a higher priority value within the same | |
17 | * module. This priority can be overridden by the application. | |
18 | */ | |
19 | #ifndef LTTNG_UST_CONSTRUCTOR_PRIO | |
20 | #define LTTNG_UST_CONSTRUCTOR_PRIO 150 | |
21 | #endif | |
22 | ||
a8909ba5 PW |
23 | #define lttng_ust_notrace __attribute__((no_instrument_function)) |
24 | ||
4f74bc5e MD |
25 | /* |
26 | * Clang supports the no_sanitize variable attribute on global variables. | |
27 | * GCC only supports the no_sanitize_address function attribute, which is | |
28 | * not what we need. | |
29 | */ | |
30 | #if defined(__clang__) | |
31 | # if __has_feature(address_sanitizer) | |
32 | # define __lttng_ust_variable_attribute_no_sanitize_address \ | |
33 | __attribute__((no_sanitize("address"))) | |
34 | # else | |
35 | # define __lttng_ust_variable_attribute_no_sanitize_address | |
36 | # endif | |
37 | #else | |
38 | # define __lttng_ust_variable_attribute_no_sanitize_address | |
39 | #endif | |
40 | ||
e1904921 MD |
41 | /* |
42 | * g++ 4.8 and prior do not support C99 compound literals. Therefore, | |
43 | * force allocating those on the heap with these C++ compilers. | |
44 | */ | |
7850c5cc MJ |
45 | #if defined (__cplusplus) && !defined (__clang__) && defined (__GNUC__) && \ |
46 | ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 8))) | |
439f90cf MD |
47 | # ifndef LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP |
48 | # define LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP | |
e1904921 MD |
49 | # endif |
50 | #endif | |
51 | ||
7edfc172 MD |
52 | /* |
53 | * Compound literals with static storage are needed by LTTng. | |
54 | * Compound literals are part of the C99 and C11 standards, but not | |
55 | * part of the C++ standards. However, those are supported by both g++ and | |
56 | * clang. In order to be strictly C++11 compliant, defining | |
439f90cf | 57 | * LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP before including this header |
7edfc172 MD |
58 | * allocates those on the heap in C++. |
59 | * | |
60 | * Example use: | |
5defa774 | 61 | * static struct mystruct *var = LTTNG_UST_COMPOUND_LITERAL(struct mystruct, { 1, 2, 3 }); |
7edfc172 | 62 | */ |
439f90cf | 63 | #if defined (__cplusplus) && defined (LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP) |
5defa774 | 64 | #define LTTNG_UST_COMPOUND_LITERAL(type, ...) new (type) __VA_ARGS__ |
7edfc172 | 65 | #else |
5defa774 | 66 | #define LTTNG_UST_COMPOUND_LITERAL(type, ...) (type[]) { __VA_ARGS__ } |
7edfc172 MD |
67 | #endif |
68 | ||
7f264068 FD |
69 | /* |
70 | * Compile time assertion. | |
71 | * - predicate: boolean expression to evaluate, | |
72 | * - msg: string to print to the user on failure when `static_assert()` is | |
73 | * supported, | |
74 | * - c_identifier_msg: message to be included in the typedef to emulate a | |
75 | * static assertion. This parameter must be a valid C identifier as it will | |
76 | * be used as a typedef name. | |
77 | */ | |
89350fda | 78 | #ifdef __cplusplus |
3a98c813 | 79 | #define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \ |
7f264068 | 80 | static_assert(predicate, msg) |
3615ef97 | 81 | #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) |
89350fda MD |
82 | #define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \ |
83 | _Static_assert(predicate, msg) | |
7f264068 FD |
84 | #else |
85 | /* | |
86 | * Evaluates the predicate and emit a compilation error on failure. | |
87 | * | |
88 | * If the predicate evaluates to true, this macro emits a typedef of an array | |
89 | * of size 0. | |
90 | * | |
91 | * If the predicate evaluates to false, this macro emits a typedef of an array | |
92 | * of negative size which is invalid in C and forces a compiler error. The msg | |
93 | * parameter is used in the tentative typedef so it is printed to the user. | |
94 | */ | |
3a98c813 | 95 | #define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \ |
b4c54822 | 96 | typedef char lttng_ust_static_assert_##c_identifier_msg[2*!!(predicate)-1] |
7f264068 FD |
97 | #endif |
98 | ||
08f6e282 MD |
99 | /* Combine two tokens. */ |
100 | #define LTTNG_UST_COMPILER__COMBINE_TOKENS(_tokena, _tokenb) \ | |
101 | _tokena##_tokenb | |
102 | #define LTTNG_UST_COMPILER_COMBINE_TOKENS(_tokena, _tokenb) \ | |
103 | LTTNG_UST_COMPILER__COMBINE_TOKENS(_tokena, _tokenb) | |
05bfa3dc JG |
104 | /* |
105 | * Wrap constructor and destructor functions to invoke them as functions with | |
0b5a6313 MD |
106 | * the constructor/destructor GNU C attributes, which ensures that those |
107 | * constructors/destructors are ordered before/after C++ | |
108 | * constructors/destructors. | |
109 | * | |
110 | * Wrap constructor and destructor functions as the constructor/destructor of a | |
111 | * variable defined within an anonymous namespace when building as C++ with | |
112 | * LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP defined. With this option, | |
113 | * there are no guarantees that the events in C++ constructors/destructors will | |
114 | * be traced. | |
05bfa3dc | 115 | */ |
0b5a6313 | 116 | #if defined (__cplusplus) && defined (LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP) |
08f6e282 MD |
117 | #define LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(name, constructor_func, \ |
118 | destructor_func, ...) \ | |
119 | namespace lttng { \ | |
120 | namespace ust { \ | |
121 | namespace details { \ | |
122 | class LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, \ | |
123 | name) { \ | |
124 | public: \ | |
801389e7 MD |
125 | LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() __VA_ARGS__; \ |
126 | ~LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() __VA_ARGS__; \ | |
08f6e282 | 127 | }; \ |
801389e7 MD |
128 | LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)::LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() \ |
129 | { \ | |
130 | constructor_func(); \ | |
131 | } \ | |
132 | LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)::~LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() \ | |
133 | { \ | |
134 | destructor_func(); \ | |
135 | } \ | |
08f6e282 MD |
136 | } \ |
137 | } \ | |
138 | } \ | |
139 | \ | |
140 | namespace { \ | |
141 | const lttng::ust::details::LTTNG_UST_COMPILER_COMBINE_TOKENS( \ | |
142 | lttng_ust_constructor_destructor_, name) \ | |
143 | LTTNG_UST_COMPILER_COMBINE_TOKENS(name, registration_instance); \ | |
05bfa3dc | 144 | } |
0b5a6313 | 145 | #else |
08f6e282 MD |
146 | #define LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(name, constructor_func, \ |
147 | destructor_func, ...) \ | |
148 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_, name)(void) \ | |
63661b66 | 149 | __attribute__((constructor(LTTNG_UST_CONSTRUCTOR_PRIO))) __VA_ARGS__; \ |
08f6e282 MD |
150 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_, name)(void) \ |
151 | { \ | |
152 | constructor_func(); \ | |
153 | } \ | |
154 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_destructor_, name)(void) \ | |
63661b66 | 155 | __attribute__((destructor(LTTNG_UST_CONSTRUCTOR_PRIO))) __VA_ARGS__; \ |
08f6e282 MD |
156 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_destructor_, name)(void) \ |
157 | { \ | |
158 | destructor_func(); \ | |
05bfa3dc JG |
159 | } |
160 | #endif | |
161 | ||
a8909ba5 | 162 | #endif /* _LTTNG_UST_COMPILER_H */ |