Pigweed
 
Loading...
Searching...
No Matches
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#ifdef __USE_MINGW_ANSI_STDIO
93#define _PW_PRINTF_FORMAT_TYPE gnu_printf
94#else
95#define _PW_PRINTF_FORMAT_TYPE printf
96#endif // __USE_MINGW_ANSI_STDIO
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