1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef FWK_ATTRIBUTES_H 9 #define FWK_ATTRIBUTES_H 10 11 #include <fwk_macros.h> 12 13 /*! 14 * \addtogroup GroupLibFramework Framework 15 * \{ 16 */ 17 18 /*! 19 * \defgroup GroupAttributes Attributes 20 * 21 * \brief Compiler-independent attribute macros. 22 * 23 * \details This component exposes a number of compiler-specific macros in a 24 * way that they can be used without causing compilation issues on 25 * compilers that do not support them. 26 * 27 * @warning Where an attribute does not modify the behaviour of a well-formed 28 * program, it may expand to nothing if the compiler in use does not 29 * support it. However, attributes for which a lack of support may 30 * fundamentally alter the program will not be defined on any compiler that 31 * does not support it. 32 * 33 * \{ 34 */ 35 36 /*! 37 * \def FWK_HAS_BUILTIN 38 * 39 * \brief Check whether the compiler supports a given builtin. 40 * 41 * \param[in] BUILTIN Builtin name. 42 * 43 * \returns A value usable in the expression of a preprocessor `if` or `elif` 44 * statement. 45 */ 46 47 #ifdef __has_builtin 48 # define FWK_HAS_BUILTIN(BUILTIN) __has_builtin(BUILTIN) 49 #else 50 # define FWK_HAS_BUILTIN(BUILTIN) 0 51 #endif 52 53 /*! 54 * \def FWK_HAS_GNU_ATTRIBUTE 55 * 56 * \brief Check whether the compiler supports a given GNU attribute. 57 * 58 * \param[in] ATTRIBUTE Attribute name. 59 * 60 * \returns A value usable in the expression of a preprocessor `if` or `elif` 61 * statement. 62 */ 63 64 #ifdef __has_attribute 65 # define FWK_HAS_GNU_ATTRIBUTE(ATTRIBUTE) __has_attribute(ATTRIBUTE) 66 #else 67 # define FWK_HAS_GNU_ATTRIBUTE(ATTRIBUTE) 0 68 #endif 69 70 /*! 71 * \def FWK_HAS_MS_ATTRIBUTE 72 * 73 * \brief Check whether the compiler supports a given Microsoft attribute. 74 * 75 * \param[in] ATTRIBUTE Attribute name. 76 * 77 * \returns A value usable in the expression of a preprocessor `if` or `elif` 78 * statement. 79 */ 80 81 #if defined(__has_declspec_attribute) && !defined(__clang__) 82 # define FWK_HAS_MS_ATTRIBUTE(ATTRIBUTE) __has_declspec_attribute(ATTRIBUTE) 83 #else 84 # define FWK_HAS_MS_ATTRIBUTE(ATTRIBUTE) 0 85 #endif 86 87 /*! 88 * \def FWK_ALLOC 89 * 90 * \brief "Allocator" attribute. 91 * 92 * \details Hints that the pointer returned by this function does not alias any 93 * other pointer, nor do any pointers to valid objects exist within the 94 * storage addressed by the pointer. 95 * 96 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute 97 * \see https://docs.microsoft.com/en-us/cpp/cpp/allocator?view=vs-2019 98 */ 99 100 #if FWK_HAS_GNU_ATTRIBUTE(__malloc__) 101 # define FWK_ALLOC_1 __attribute__((__malloc__)) 102 #else 103 # define FWK_ALLOC_1 104 #endif 105 106 #if FWK_HAS_MS_ATTRIBUTE(allocator) 107 # define FWK_ALLOC_2 __declspec(allocator) 108 #else 109 # define FWK_ALLOC_2 110 #endif 111 112 #if FWK_HAS_MS_ATTRIBUTE(restrict) 113 # define FWK_ALLOC_3 __declspec(restrict) 114 #else 115 # define FWK_ALLOC_3 116 #endif 117 118 #define FWK_ALLOC FWK_ALLOC_1 FWK_ALLOC_2 FWK_ALLOC_3 119 120 /*! 121 * \def FWK_ALLOC_SIZE1 122 * 123 * \brief "Sizing allocator" attribute. 124 * 125 * \details Hints that the pointer returned by this function has a size given 126 * by a parameter. 127 * 128 * \param[in] SIZE_POS Position of the size parameter, 1-indexed. 129 * 130 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute 131 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-alloc_005fsize-variable-attribute 132 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-alloc_005fsize-type-attribute 133 */ 134 135 /*! 136 * \def FWK_ALLOC_SIZE2 137 * 138 * \brief "Sizing allocator" attribute. 139 * 140 * \details Hints that the pointer returned by this function has a size given 141 * by the product of a size and a count parameter. 142 * 143 * \param[in] SIZE_POS Position of the size parameter, 1-indexed. 144 * \param[in] COUNT_POS Position of the count parameter, 1-indexed. 145 * 146 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute 147 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-alloc_005fsize-variable-attribute 148 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-alloc_005fsize-type-attribute 149 */ 150 151 #if FWK_HAS_GNU_ATTRIBUTE(__alloc_size__) 152 # define FWK_ALLOC_SIZE1(SIZE_POS) __attribute__((__alloc_size__(SIZE_POS))) 153 # define FWK_ALLOC_SIZE2(SIZE_POS, COUNT_POS) \ 154 __attribute__((__alloc_size__(SIZE_POS, COUNT_POS))) 155 #else 156 # define FWK_ALLOC_SIZE1(SIZE_POS) 157 # define FWK_ALLOC_SIZE2(SIZE_POS, COUNT_POS) 158 #endif 159 160 /*! 161 * \def FWK_ALLOC_ALIGN 162 * 163 * \brief "Aligning allocator" attribute. 164 * 165 * \details Hints that the pointer returned by this function has an alignment 166 * given by a parameter. 167 * 168 * \param[in] ALIGN_POS Position of the alignment parameter, 1-indexed. 169 * 170 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005falign-function-attribute 171 */ 172 173 #if FWK_HAS_GNU_ATTRIBUTE(__alloc_align__) 174 # define FWK_ALLOC_ALIGN(ALIGN_POS) \ 175 __attribute__((__alloc_align__(ALIGN_POS))) 176 #else 177 # define FWK_ALLOC_ALIGN(ALIGN_POS) 178 #endif 179 180 /*! 181 * \def FWK_WEAK 182 * 183 * \brief "Weak" attribute. 184 * 185 * \details Applies weak linkage to the item. 186 * 187 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute 188 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute 189 */ 190 191 #if FWK_HAS_GNU_ATTRIBUTE(__weak__) 192 # define FWK_WEAK __attribute__((__weak__)) 193 #endif 194 195 /*! 196 * \def FWK_PRINTF 197 * 198 * \brief "`printf`-like" attribute. 199 * 200 * \details Hints that the function takes a string literal with the same 201 * semantics as the `printf` format string. 202 * 203 * \param[in] STR_POS Position of the format string parameter, 1-indexed. 204 * \param[in] VA_POS Position of the argument list, 1-indexed. 205 * 206 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-Wformat-3 207 */ 208 209 #if FWK_HAS_GNU_ATTRIBUTE(__format__) 210 # define FWK_PRINTF(STR_POS, VA_POS) \ 211 __attribute__((__format__(printf, STR_POS, VA_POS))) 212 #else 213 # define FWK_PRINTF(STR_POS, VA_POS) 214 #endif 215 216 /*! 217 * \def FWK_CONSTRUCTOR 218 * 219 * \brief "Constructor" attribute. 220 * 221 * \details Adds the function to the list of functions to be executed before 222 * `main`. 223 * 224 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-constructor-function-attribute 225 */ 226 227 #if FWK_HAS_GNU_ATTRIBUTE(__constructor__) 228 # define FWK_CONSTRUCTOR __attribute__((__constructor__)) 229 #endif 230 231 /*! 232 * \def FWK_PACKED 233 * 234 * \brief "Packed" attribute. 235 * 236 * \details Packs the item that this attribute is attached to. 237 * 238 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute 239 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute 240 */ 241 242 #if FWK_HAS_GNU_ATTRIBUTE(__packed__) 243 # define FWK_PACKED __attribute__((__packed__)) 244 #endif 245 246 /*! 247 * \def FWK_SECTION 248 * 249 * \brief "Linker section" attribute. 250 * 251 * \details Places the item that this attribute is attached to into a particular 252 * linker section. 253 * 254 * \param[in] SECTION String literal representing the name of the section. 255 * 256 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute 257 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute 258 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute 259 */ 260 261 #if FWK_HAS_GNU_ATTRIBUTE(__section__) 262 # define FWK_SECTION(SECTION) __attribute__((__section__(SECTION))) 263 #endif 264 265 /*! 266 * \def FWK_DEPRECATED 267 * 268 * \brief "Deprecated" attribute. 269 * 270 * \details Marks the item that this attribute is attached to as deprecated. 271 * 272 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute 273 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute 274 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute 275 * \see https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute 276 */ 277 278 #if FWK_HAS_GNU_ATTRIBUTE(__deprecated__) 279 # define FWK_DEPRECATED __attribute__((__deprecated__)) 280 #else 281 # define FWK_DEPRECATED 282 #endif 283 284 /*! 285 * \def FWK_NOINLINE 286 * 287 * \brief "Do not inline" attribute. 288 * 289 * \details Hints to the compiler that the function should not be inlined. 290 * 291 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute 292 */ 293 294 #if FWK_HAS_GNU_ATTRIBUTE(__noinline__) 295 # define FWK_NOINLINE __attribute__((__noinline__)) 296 #else 297 # define FWK_NOINLINE 298 #endif 299 300 /*! 301 * \def FWK_WARN_UNUSED 302 * 303 * \brief "Warn on unused result" attribute. 304 * 305 * \details Hints that it is a possible error to ignore the result of a 306 * function. 307 * 308 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-warn_005funused_005fresult-function-attribute 309 */ 310 311 #if FWK_HAS_GNU_ATTRIBUTE(__warn_unused_result__) 312 # define FWK_WARN_UNUSED __attribute__((__warn_unused_result__)) 313 #else 314 # define FWK_WARN_UNUSED 315 #endif 316 317 /*! 318 * \def FWK_LEAF 319 * 320 * \brief "Leaf" attribute. 321 * 322 * \details Specifies that the function will return to the current compilation 323 * unit only by returning or by throwing an exception. 324 * 325 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-leaf-function-attribute 326 */ 327 328 #if FWK_HAS_GNU_ATTRIBUTE(__leaf__) 329 # define FWK_LEAF __attribute__((__leaf__)) 330 #else 331 # define FWK_LEAF 332 #endif 333 334 /*! 335 * \def FWK_NOTHROW 336 * 337 * \brief "Doesn't throw" attribute. 338 * 339 * \details Specifies that the function will not throw an exception, either 340 * directly or indirectly. 341 * 342 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-nothrow-function-attribute 343 */ 344 345 #if FWK_HAS_GNU_ATTRIBUTE(__nothrow__) 346 # define FWK_NOTHROW __attribute__((__nothrow__)) 347 #else 348 # define FWK_NOTHROW 349 #endif 350 351 /*! 352 * \def FWK_CONST 353 * 354 * \brief "Strictly pure" attribute. 355 * 356 * \details Hints that the function will consistently return the same result for 357 * the same input and will not make any changes to the observable state 358 * of the program. 359 * 360 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute 361 */ 362 363 #if FWK_HAS_GNU_ATTRIBUTE(__const__) 364 # define FWK_CONST __attribute__((__const__)) 365 #else 366 # define FWK_CONST 367 #endif 368 369 /*! 370 * \def FWK_PURE 371 * 372 * \brief "Pure" attribute. 373 * 374 * \details Hints that the function will consistently return the same result for 375 * the same input and will not make any changes to the observable state 376 * of the program, but may read non-volatile objects not given as an input 377 * to the function 378 * 379 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute 380 */ 381 382 #if FWK_HAS_GNU_ATTRIBUTE(__pure__) 383 # define FWK_PURE __attribute__((__pure__)) 384 #else 385 # define FWK_PURE 386 #endif 387 388 /*! 389 * \def FWK_READ_ONLY1 390 * 391 * \brief "Read only" attribute. 392 * 393 * \details Hints that the function takes a reference to an object which is read 394 * from but not written to, and that the object must therefore be 395 * initialized. 396 * 397 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 398 * 399 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 400 */ 401 402 /*! 403 * \def FWK_READ_ONLY2 404 * 405 * \brief "Read only" attribute. 406 * 407 * \details Hints that the function takes a reference to an object with a given 408 * size which is read from but not written to, and that the object must 409 * therefore be initialized. 410 * 411 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 412 * \param[in] SIZE_POS Position of the size parameter, 1-indexed. 413 * 414 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 415 */ 416 417 #if FWK_HAS_GNU_ATTRIBUTE(__access__) 418 # define FWK_READ_ONLY1(REF_POS) \ 419 __attribute__((__access__(read_only, REF_POS))) 420 # define FWK_READ_ONLY2(REF_POS, SIZE_POS) \ 421 __attribute__((__access__(read_only, REF_POS, SIZE_POS))) 422 #else 423 # define FWK_READ_ONLY1(REF_POS) 424 # define FWK_READ_ONLY2(REF_POS, SIZE_POS) 425 #endif 426 427 /*! 428 * \def FWK_WRITE_ONLY1 429 * 430 * \brief "Write only" attribute. 431 * 432 * \details Hints that the function takes a reference to an object which is 433 * written to but not read from, and that the object is therefore permitted 434 * to be uninitialized. 435 * 436 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 437 * 438 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 439 */ 440 441 /*! 442 * \def FWK_WRITE_ONLY2 443 * 444 * \brief "Write only" attribute. 445 * 446 * \details Hints that the function takes a reference to an object with a given 447 * size which is written to but not read from, and that the object is 448 * therefore permitted to be uninitialized. 449 * 450 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 451 * \param[in] SIZE_POS Position of the size parameter, 1-indexed. 452 * 453 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 454 */ 455 456 #if FWK_HAS_GNU_ATTRIBUTE(__access__) 457 # define FWK_WRITE_ONLY1(REF_POS) \ 458 __attribute__((__access__(write_only, REF_POS))) 459 # define FWK_WRITE_ONLY2(REF_POS, SIZE_POS) \ 460 __attribute__((__access__(write_only, REF_POS, SIZE_POS))) 461 #else 462 # define FWK_WRITE_ONLY1(REF_POS) 463 # define FWK_WRITE_ONLY2(REF_POS, SIZE_POS) 464 #endif 465 466 /*! 467 * \def FWK_READ_WRITE1 468 * 469 * \brief "Read/write" attribute. 470 * 471 * \details Hints that the function takes a reference to an object which is 472 * both read from and written to, and that the object must therefore be 473 * initialized. 474 * 475 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 476 * 477 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 478 */ 479 480 /*! 481 * \def FWK_READ_WRITE2 482 * 483 * \brief "Read/write" attribute. 484 * 485 * \details Hints that the function takes a reference to an object with a given 486 * size which is both read from and written to, and that the object must 487 * therefore be initialized. 488 * 489 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 490 * \param[in] SIZE_POS Position of the size parameter, 1-indexed. 491 * 492 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 493 */ 494 495 #if FWK_HAS_GNU_ATTRIBUTE(__access__) 496 # define FWK_READ_WRITE1(REF_POS) \ 497 __attribute__((__access__(read_write, REF_POS))) 498 # define FWK_READ_WRITE2(REF_POS, SIZE_POS) \ 499 __attribute__((__access__(read_write, REF_POS, SIZE_POS))) 500 #else 501 # define FWK_READ_WRITE1(REF_POS) 502 # define FWK_READ_WRITE2(REF_POS, SIZE_POS) 503 #endif 504 505 /*! 506 * \def FWK_UNTOUCHED 507 * 508 * \brief "Untouched" attribute. 509 * 510 * \details Hints that the function takes a reference to an object which is 511 * neither read from nor written to, but for which the reference itself is 512 * used. 513 * 514 * \param[in] REF_POS Position of the reference parameter, 1-indexed. 515 * 516 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html 517 */ 518 519 #if FWK_HAS_GNU_ATTRIBUTE(__access__) && __GNUC__ >= 11 520 # define FWK_UNTOUCHED(REF_POS) __attribute__((__access__(none, REF_POS))) 521 #else 522 # define FWK_UNTOUCHED(REF_POS) 523 #endif 524 525 /*! 526 * \def FWK_NONNULL 527 * 528 * \brief "Non-null" attribute. 529 * 530 * \details Hints that the the function takes a pointer that should not be null. 531 * 532 * \param[in] PTR_POS Position of the pointer parameter, 1-indexed. 533 * 534 * \see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-nonnull-function-attribute 535 */ 536 537 #if FWK_HAS_GNU_ATTRIBUTE(__nonnull__) 538 # define FWK_NONNULL(PTR_POS) __attribute__((__nonnull__(PTR_POS))) 539 #else 540 # define FWK_NONNULL(PTR_POS) 541 #endif 542 543 /*! 544 * \def FWK_FALLTHROUGH 545 * 546 * \brief "Fallthrough" attribute. 547 * 548 * \details Hints that a fallthrough in a switch statement is intended. 549 * 550 * \see https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#index-fallthrough-statement-attribute 551 */ 552 553 #if FWK_HAS_GNU_ATTRIBUTE(__fallthrough__) 554 # define FWK_FALLTHROUGH __attribute__((__fallthrough__)) 555 #else 556 # define FWK_FALLTHROUGH 557 #endif 558 559 /*! 560 * \} 561 */ 562 563 /*! 564 * \} 565 */ 566 567 #endif /* FWK_ATTRIBUTES_H */ 568