C/C++ API Reference
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
32
60#define PW_PACKED(declaration) declaration __attribute__((packed))
61
63#define PW_USED __attribute__((used))
64
67#define PW_NO_PROLOGUE __attribute__((naked))
68
89#define PW_PRINTF_FORMAT(format_index, parameter_index) \
90 __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index)))
91
95#if defined(__USE_MINGW_ANSI_STDIO) && !defined(__clang__)
96#define _PW_PRINTF_FORMAT_TYPE gnu_printf
97#else
98#define _PW_PRINTF_FORMAT_TYPE printf
99#endif // defined(__USE_MINGW_ANSI_STDIO) && !defined(__clang__)
100
102#ifdef __APPLE__
103#define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA," name)))
104#else
105#define PW_PLACE_IN_SECTION(name) __attribute__((section(name)))
106#endif // __APPLE__
107
112#ifdef __APPLE__
113#define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used))
114#else
115#define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used))
116#endif // __APPLE__
117
123#define PW_NO_RETURN __attribute__((noreturn))
124
126#define PW_NO_INLINE __attribute__((noinline))
127
138#define PW_UNREACHABLE __builtin_unreachable()
139
155#ifdef __clang__
156#define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
157#else
158#define PW_NO_SANITIZE(check)
159#endif // __clang__
160
164#ifdef __has_attribute
165#define PW_HAVE_ATTRIBUTE(x) __has_attribute(x)
166#else
167#define PW_HAVE_ATTRIBUTE(x) 0
168#endif // __has_attribute
169
177#if defined(__cplusplus) && defined(__has_cpp_attribute)
178#define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
179#else
180#define PW_HAVE_CPP_ATTRIBUTE(x) 0
181#endif // defined(__cplusplus) && defined(__has_cpp_attribute)
182
184#define _PW_REQUIRE_SEMICOLON \
185 static_assert(1, "This macro must be terminated with a semicolon")
186
189#define PW_MODIFY_DIAGNOSTICS_PUSH() \
190 _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON
191
194#define PW_MODIFY_DIAGNOSTICS_POP() \
195 _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON
196
203#define PW_MODIFY_DIAGNOSTIC(kind, option) \
204 PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON
205
208#ifdef __clang__
209#define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON
210#else
211#define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \
212 PW_MODIFY_DIAGNOSTIC(kind, option)
213#endif // __clang__
214
217#ifdef __clang__
218#define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) \
219 PW_MODIFY_DIAGNOSTIC(kind, option)
220#else
221#define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) _PW_REQUIRE_SEMICOLON
222#endif // __clang__
223
226#define PW_PRAGMA(contents) _Pragma(#contents)
227
238#define PW_WEAK __attribute__((weak))
239
250#define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to)))
251
268#if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
269#define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
270#elif PW_HAVE_ATTRIBUTE(lifetimebound)
271#define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
272#else
273#define PW_ATTRIBUTE_LIFETIME_BOUND
274#endif // PW_ATTRIBUTE_LIFETIME_BOUND
275
278#if (defined(__clang_major__) && __clang_major__ < 9) || \
279 (defined(__GNUC__) && __GNUC__ < 12)
280#define PW_VA_OPT_SUPPORTED() 0 // Don't bother checking on old compilers.
281#else
282#define PW_VA_OPT_SUPPORTED() _PW_VA_OPT_SUPPORTED()
284
285#define _PW_VA_OPT_SUPPORTED(...) _PW_VA_OPT_SUPPORTED_##__VA_OPT__()
286#define _PW_VA_OPT_SUPPORTED_ 1
287#define _PW_VA_OPT_SUPPORTED___VA_OPT__() 0
288
289#endif // __clang_major__ < 9 || __GNUC__ < 12
290
294#if PW_HAVE_CPP_ATTRIBUTE(no_unique_address)
295#define PW_NO_UNIQUE_ADDRESS [[no_unique_address]]
296#else
297#define PW_NO_UNIQUE_ADDRESS
298#endif // PW_NO_UNIQUE_ADDRESS