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 | * | |
4c3d9cd0 MD |
88 | * If the predicate evaluates to true, this macro emits a function |
89 | * prototype with an argument type which is an array of size 0. | |
7f264068 | 90 | * |
4c3d9cd0 MD |
91 | * If the predicate evaluates to false, this macro emits a function |
92 | * prototype with an argument type which is an array of negative size | |
93 | * which is invalid in C and forces a compiler error. The | |
94 | * c_identifier_msg parameter is used as the argument identifier so it | |
95 | * is printed to the user when the error is reported. | |
7f264068 | 96 | */ |
3a98c813 | 97 | #define lttng_ust_static_assert(predicate, msg, c_identifier_msg) \ |
4c3d9cd0 | 98 | void lttng_ust_static_assert_proto(char c_identifier_msg[2*!!(predicate)-1]) |
7f264068 FD |
99 | #endif |
100 | ||
08f6e282 MD |
101 | /* Combine two tokens. */ |
102 | #define LTTNG_UST_COMPILER__COMBINE_TOKENS(_tokena, _tokenb) \ | |
103 | _tokena##_tokenb | |
104 | #define LTTNG_UST_COMPILER_COMBINE_TOKENS(_tokena, _tokenb) \ | |
105 | LTTNG_UST_COMPILER__COMBINE_TOKENS(_tokena, _tokenb) | |
05bfa3dc JG |
106 | /* |
107 | * Wrap constructor and destructor functions to invoke them as functions with | |
0b5a6313 MD |
108 | * the constructor/destructor GNU C attributes, which ensures that those |
109 | * constructors/destructors are ordered before/after C++ | |
110 | * constructors/destructors. | |
111 | * | |
112 | * Wrap constructor and destructor functions as the constructor/destructor of a | |
113 | * variable defined within an anonymous namespace when building as C++ with | |
114 | * LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP defined. With this option, | |
115 | * there are no guarantees that the events in C++ constructors/destructors will | |
116 | * be traced. | |
05bfa3dc | 117 | */ |
0b5a6313 | 118 | #if defined (__cplusplus) && defined (LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP) |
08f6e282 MD |
119 | #define LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(name, constructor_func, \ |
120 | destructor_func, ...) \ | |
121 | namespace lttng { \ | |
122 | namespace ust { \ | |
123 | namespace details { \ | |
124 | class LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, \ | |
125 | name) { \ | |
126 | public: \ | |
801389e7 MD |
127 | LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() __VA_ARGS__; \ |
128 | ~LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() __VA_ARGS__; \ | |
08f6e282 | 129 | }; \ |
801389e7 MD |
130 | LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)::LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() \ |
131 | { \ | |
132 | constructor_func(); \ | |
133 | } \ | |
134 | LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)::~LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_destructor_, name)() \ | |
135 | { \ | |
136 | destructor_func(); \ | |
137 | } \ | |
08f6e282 MD |
138 | } \ |
139 | } \ | |
140 | } \ | |
141 | \ | |
142 | namespace { \ | |
143 | const lttng::ust::details::LTTNG_UST_COMPILER_COMBINE_TOKENS( \ | |
144 | lttng_ust_constructor_destructor_, name) \ | |
145 | LTTNG_UST_COMPILER_COMBINE_TOKENS(name, registration_instance); \ | |
05bfa3dc | 146 | } |
0b5a6313 | 147 | #else |
08f6e282 MD |
148 | #define LTTNG_UST_DECLARE_CONSTRUCTOR_DESTRUCTOR(name, constructor_func, \ |
149 | destructor_func, ...) \ | |
150 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_, name)(void) \ | |
63661b66 | 151 | __attribute__((constructor(LTTNG_UST_CONSTRUCTOR_PRIO))) __VA_ARGS__; \ |
08f6e282 MD |
152 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_constructor_, name)(void) \ |
153 | { \ | |
154 | constructor_func(); \ | |
155 | } \ | |
156 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_destructor_, name)(void) \ | |
63661b66 | 157 | __attribute__((destructor(LTTNG_UST_CONSTRUCTOR_PRIO))) __VA_ARGS__; \ |
08f6e282 MD |
158 | static void LTTNG_UST_COMPILER_COMBINE_TOKENS(lttng_ust_destructor_, name)(void) \ |
159 | { \ | |
160 | destructor_func(); \ | |
05bfa3dc JG |
161 | } |
162 | #endif | |
163 | ||
a8909ba5 | 164 | #endif /* _LTTNG_UST_COMPILER_H */ |