• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <assert.h>
20 
21 // TODO(b/234877280): compiler.h should be refactored out of pw_preprocessor as
22 // the scope is outside of the module. Perhaps it should be split up and placed
23 // under pw_compiler, e.g. pw_compiler/attributes.h & pw_compiler/builtins.h.
24 
25 // Marks a struct or class as packed.
26 #define PW_PACKED(declaration) declaration __attribute__((packed))
27 
28 // Marks a function or object as used, ensuring code for it is generated.
29 #define PW_USED __attribute__((used))
30 
31 // Prevents generation of a prologue or epilogue for a function. This is
32 // helpful when implementing the function in assembly.
33 #define PW_NO_PROLOGUE __attribute__((naked))
34 
35 // Marks that a function declaration takes a printf-style format string and
36 // variadic arguments. This allows the compiler to perform check the validity of
37 // the format string and arguments. This macro must only be on the function
38 // declaration, not the definition.
39 //
40 // The format_index is index of the format string parameter and parameter_index
41 // is the starting index of the variadic arguments. Indices start at 1. For C++
42 // class member functions, add one to the index to account for the implicit this
43 // parameter.
44 //
45 // This example shows a function where the format string is argument 2 and the
46 // varargs start at argument 3.
47 //
48 //   int PrintfStyleFunction(char* buffer,
49 //                           const char* fmt, ...) PW_PRINTF_FORMAT(2,3);
50 //
51 //   int PrintfStyleFunction(char* buffer, const char* fmt, ...) {
52 //     ... implementation here ...
53 //   }
54 //
55 
56 // When compiling for host using MinGW, use gnu_printf() rather than printf()
57 // to support %z format specifiers.
58 #ifdef __USE_MINGW_ANSI_STDIO
59 #define _PW_PRINTF_FORMAT_TYPE gnu_printf
60 #else
61 #define _PW_PRINTF_FORMAT_TYPE printf
62 #endif  // __USE_MINGW_ANSI_STDIO
63 
64 #define PW_PRINTF_FORMAT(format_index, parameter_index) \
65   __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index)))
66 
67 // Places a variable in the specified linker section.
68 #ifdef __APPLE__
69 #define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA," name)))
70 #else
71 #define PW_PLACE_IN_SECTION(name) __attribute__((section(name)))
72 #endif  // __APPLE__
73 
74 // Places a variable in the specified linker section and directs the compiler
75 // to keep the variable, even if it is not used. Depending on the linker
76 // options, the linker may still remove this section if it is not declared in
77 // the linker script and marked KEEP.
78 #ifdef __APPLE__
79 #define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used))
80 #else
81 #define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used))
82 #endif  // __APPLE__
83 
84 // Indicate to the compiler that the annotated function won't return. Example:
85 //
86 //   PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code);
87 //
88 #define PW_NO_RETURN __attribute__((noreturn))
89 
90 // Prevents the compiler from inlining a fuction.
91 #define PW_NO_INLINE __attribute__((noinline))
92 
93 // Indicate to the compiler that the given section of code will not be reached.
94 // Example:
95 //
96 //   int main() {
97 //     InitializeBoard();
98 //     vendor_StartScheduler();  // Note: vendor forgot noreturn attribute.
99 //     PW_UNREACHABLE;
100 //   }
101 //
102 #define PW_UNREACHABLE __builtin_unreachable()
103 
104 // Indicate to a sanitizer compiler runtime to skip the named check in the
105 // associated function.
106 // Example:
107 //
108 //   uint32_t djb2(const void* buf, size_t len)
109 //       PW_NO_SANITIZE("unsigned-integer-overflow"){
110 //     uint32_t hash = 5381;
111 //     const uint8_t* u8 = static_cast<const uint8_t*>(buf);
112 //     for (size_t i = 0; i < len; ++i) {
113 //       hash = (hash * 33) + u8[i]; /* hash * 33 + c */
114 //     }
115 //     return hash;
116 //   }
117 #ifdef __clang__
118 #define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
119 #else
120 #define PW_NO_SANITIZE(check)
121 #endif  // __clang__
122 
123 // Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and
124 // evaluates to a non zero constant integer if the attribute is supported or 0
125 // if not.
126 #ifdef __has_attribute
127 #define PW_HAVE_ATTRIBUTE(x) __has_attribute(x)
128 #else
129 #define PW_HAVE_ATTRIBUTE(x) 0
130 #endif  // __has_attribute
131 
132 // A function-like feature checking macro that accepts C++11 style attributes.
133 // It's a wrapper around __has_cpp_attribute
134 // (https://en.cppreference.com/w/cpp/feature_test), borrowed from
135 // ABSL_HAVE_CPP_ATTRIBUTE. If there is no __has_cpp_attribute, evaluates to 0.
136 #if defined(__cplusplus) && defined(__has_cpp_attribute)
137 #define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
138 #else
139 #define PW_HAVE_CPP_ATTRIBUTE(x) 0
140 #endif  // defined(__cplusplus) && defined(__has_cpp_attribute)
141 
142 #define _PW_REQUIRE_SEMICOLON \
143   static_assert(1, "This macro must be terminated with a semicolon")
144 
145 // PW_MODIFY_DIAGNOSTICS_PUSH and PW_MODIFY_DIAGNOSTICS_POP are used to turn off
146 // or on diagnostics (warnings or errors) for a section of code. Use
147 // PW_MODIFY_DIAGNOSTICS_PUSH, use PW_MODIFY_DIAGNOSTIC as many times as needed,
148 // then use PW_MODIFY_DIAGNOSTICS_POP to restore the previous settings.
149 #define PW_MODIFY_DIAGNOSTICS_PUSH() \
150   _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON
151 #define PW_MODIFY_DIAGNOSTICS_POP() \
152   _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON
153 
154 // Changes how a diagnostic (warning or error) is handled. Most commonly used to
155 // disable warnings. PW_MODIFY_DIAGNOSTIC should be used between
156 // PW_MODIFY_DIAGNOSTICS_PUSH and PW_MODIFY_DIAGNOSTICS_POP statements to avoid
157 // applying the modifications too broadly.
158 //
159 // 'kind' must be one of warning, error, or ignored.
160 #define PW_MODIFY_DIAGNOSTIC(kind, option) \
161   PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON
162 
163 // Applies PW_MODIFY_DIAGNOSTIC only for GCC. This is useful for warnings that
164 // aren't supported by or don't need to be changed in other compilers.
165 #ifdef __clang__
166 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON
167 #else
168 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \
169   PW_MODIFY_DIAGNOSTIC(kind, option)
170 #endif  // __clang__
171 
172 // Expands to a _Pragma with the contents as a string. _Pragma must take a
173 // single string literal; this can be used to construct a _Pragma argument.
174 #define PW_PRAGMA(contents) _Pragma(#contents)
175 
176 // Marks a function or object as weak, allowing the definition to be overriden.
177 //
178 // This can be useful when supporting third-party SDKs which may conditionally
179 // compile in code, for example:
180 //
181 //   PW_WEAK void SysTick_Handler(void) {
182 //     // Default interrupt handler that might be overriden.
183 //   }
184 #define PW_WEAK __attribute__((weak))
185 
186 // Marks a weak function as an alias to another, allowing the definition to
187 // be given a default and overriden.
188 //
189 // This can be useful when supporting third-party SDKs which may conditionally
190 // compile in code, for example:
191 //
192 //   // Driver handler replaced with default unless overridden.
193 //   void USART_DriverHandler(void) PW_ALIAS(DefaultDriverHandler);
194 #define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to)))
195 
196 // PW_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function
197 // parameter or implicit object parameter is retained by the return value of the
198 // annotated function (or, for a parameter of a constructor, in the value of the
199 // constructed object). This attribute causes warnings to be produced if a
200 // temporary object does not live long enough.
201 //
202 // When applied to a reference parameter, the referenced object is assumed to be
203 // retained by the return value of the function. When applied to a non-reference
204 // parameter (for example, a pointer or a class type), all temporaries
205 // referenced by the parameter are assumed to be retained by the return value of
206 // the function.
207 //
208 // See also the upstream documentation:
209 // https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
210 //
211 // This is a copy of ABSL_ATTRIBUTE_LIFETIME_BOUND.
212 #if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
213 #define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
214 #elif PW_HAVE_ATTRIBUTE(lifetimebound)
215 #define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
216 #else
217 #define PW_ATTRIBUTE_LIFETIME_BOUND
218 #endif  // PW_ATTRIBUTE_LIFETIME_BOUND
219