Pigweed
C/C++ API Reference
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Modules
Pages
Loading...
Searching...
No Matches
pw_preprocessor
public
pw_preprocessor
compiler.h
1
// Copyright 2019 The Pigweed Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
// use this file except in compliance with the License. You may obtain a copy of
5
// the License at
6
//
7
// https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
// License for the specific language governing permissions and limitations under
13
// the License.
14
//
15
// Preprocessor macros that wrap compiler-specific features.
16
// This file is used by both C++ and C code.
17
#pragma once
18
19
// TODO: b/234877280 - compiler.h should be refactored out of pw_preprocessor as
20
// the scope is outside of the module. Perhaps it should be split up and placed
21
// under pw_compiler, e.g. pw_compiler/attributes.h & pw_compiler/builtins.h.
22
23
#include "pw_polyfill/static_assert.h"
24
26
29
57
#define PW_PACKED(declaration) declaration __attribute__((packed))
58
60
#define PW_USED __attribute__((used))
61
64
#define PW_NO_PROLOGUE __attribute__((naked))
65
86
#define PW_PRINTF_FORMAT(format_index, parameter_index) \
87
__attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index)))
88
92
#if defined(__USE_MINGW_ANSI_STDIO) && !defined(__clang__)
93
#define _PW_PRINTF_FORMAT_TYPE gnu_printf
94
#else
95
#define _PW_PRINTF_FORMAT_TYPE printf
96
#endif
// defined(__USE_MINGW_ANSI_STDIO) && !defined(__clang__)
97
99
#ifdef __APPLE__
100
#define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA,"
name)))
101
#else
102
#define PW_PLACE_IN_SECTION(name) __attribute__((section(name)))
103
#endif
// __APPLE__
104
109
#ifdef __APPLE__
110
#define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA,"
name), used))
111
#else
112
#define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used))
113
#endif
// __APPLE__
114
120
#define PW_NO_RETURN __attribute__((noreturn))
121
123
#define PW_NO_INLINE __attribute__((noinline))
124
135
#define PW_UNREACHABLE __builtin_unreachable()
136
152
#ifdef __clang__
153
#define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
154
#else
155
#define PW_NO_SANITIZE(check)
156
#endif
// __clang__
157
161
#ifdef __has_attribute
162
#define PW_HAVE_ATTRIBUTE(x) __has_attribute(x)
163
#else
164
#define PW_HAVE_ATTRIBUTE(x) 0
165
#endif
// __has_attribute
166
174
#if defined(__cplusplus) && defined(__has_cpp_attribute)
175
#define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
176
#else
177
#define PW_HAVE_CPP_ATTRIBUTE(x) 0
178
#endif
// defined(__cplusplus) && defined(__has_cpp_attribute)
179
181
#define _PW_REQUIRE_SEMICOLON \
182
static_assert(1, "This macro must be terminated with a semicolon"
)
183
186
#define PW_MODIFY_DIAGNOSTICS_PUSH() \
187
_Pragma("GCC diagnostic push"
) _PW_REQUIRE_SEMICOLON
188
191
#define PW_MODIFY_DIAGNOSTICS_POP() \
192
_Pragma("GCC diagnostic pop"
) _PW_REQUIRE_SEMICOLON
193
200
#define PW_MODIFY_DIAGNOSTIC(kind, option) \
201
PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON
202
205
#ifdef __clang__
206
#define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON
207
#else
208
#define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \
209
PW_MODIFY_DIAGNOSTIC(kind, option)
210
#endif
// __clang__
211
214
#ifdef __clang__
215
#define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) \
216
PW_MODIFY_DIAGNOSTIC(kind, option)
217
#else
218
#define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) _PW_REQUIRE_SEMICOLON
219
#endif
// __clang__
220
223
#define PW_PRAGMA(contents) _Pragma(#contents)
224
235
#define PW_WEAK __attribute__((weak))
236
247
#define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to)))
248
265
#if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
266
#define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
267
#elif PW_HAVE_ATTRIBUTE(lifetimebound)
268
#define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
269
#else
270
#define PW_ATTRIBUTE_LIFETIME_BOUND
271
#endif
// PW_ATTRIBUTE_LIFETIME_BOUND
272
282
#define PW_ADD_OVERFLOW(a, b, out) __builtin_add_overflow(a, b, out)
283
294
#define PW_SUB_OVERFLOW(a, b, out) __builtin_sub_overflow(a, b, out)
295
304
#define PW_MUL_OVERFLOW(a, b, out) __builtin_mul_overflow(a, b, out)
305
308
#if (defined(__clang_major__) && __clang_major__ < 9) || \
309
(defined(__GNUC__) && __GNUC__ < 12)
310
#define PW_VA_OPT_SUPPORTED() 0
// Don't bother checking on old compilers.
311
#else
312
#define PW_VA_OPT_SUPPORTED() _PW_VA_OPT_SUPPORTED()
314
315
#define _PW_VA_OPT_SUPPORTED(...) _PW_VA_OPT_SUPPORTED_##__VA_OPT__()
316
#define _PW_VA_OPT_SUPPORTED_ 1
317
#define _PW_VA_OPT_SUPPORTED___VA_OPT__() 0
318
319
#endif
// __clang_major__ < 9 || __GNUC__ < 12
320
324
#if PW_HAVE_CPP_ATTRIBUTE(no_unique_address)
325
#define PW_NO_UNIQUE_ADDRESS [[no_unique_address]]
326
#else
327
#define PW_NO_UNIQUE_ADDRESS
328
#endif
// PW_NO_UNIQUE_ADDRESS
Generated by
1.9.6