1/*
2 * Copyright 2017, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
8 * See "LICENSE_BSD2.txt" for details.
9 *
10 * @TAG(DATA61_BSD)
11 */
12
13#pragma once
14
15/* macros for compile time attributes */
16
17/* Stub out Clang feature macros for GCC. */
18#ifndef __has_attribute
19  #define __has_attribute(attrib) 0
20#endif
21#ifndef __has_extension
22  #define __has_extension(ext) 0
23#endif
24#ifndef __has_feature
25  #define __has_feature(feature) 0
26#endif
27
28#define ALIAS(sym)   __attribute__((alias(#sym)))
29#define ALIGN(n)     __attribute__((__aligned__(n)))
30#define ALLOC_SIZE(args...) __attribute__((alloc_size(args)))
31#define ASSUME_ALIGNED(args...) __attribute__((assume_aligned(args)))
32#define NO_INLINE        __attribute__((noinline))
33#define ALWAYS_INLINE __attribute__((always_inline))
34#define CLEANUP(fn)  __attribute__((cleanup(fn)))
35#if (defined(__clang__) && __has_attribute(cold)) || (!defined(__clang__) && defined(__GNUC__))
36  #define COLD       __attribute__((cold))
37#else
38  #define COLD       /* ignored */
39#endif
40#define DEPRECATED(msg) __attribute__((deprecated(msg)))
41#if defined(__clang__) && __has_extension(attribute_unavailable_with_message)
42  #define ERROR(msg)   __attribute__((unavailable(msg)))
43#elif defined(__GNUC__)
44  #define ERROR(msg)   __attribute__((error(msg)))
45#else
46  /* No good compile-time error feature. Just emit garbage that will force an unclean error. */
47  #define ERROR(msg)  __COMPILE_TIME_ERROR_SUPPORT_UNAVAILABLE(msg)
48#endif
49#if (defined(__clang__) && __has_attribute(hot)) || (!defined(__clang__) && defined(__GNUC__))
50  #define HOT        __attribute__((hot))
51#else
52  #define HOT        /* ignored */
53#endif
54#define MALLOC       __attribute__((malloc))
55#define NONNULL(args...) __attribute__((__nonnull__(args)))
56#define NONNULL_ALL  __attribute__((__nonnull__))
57#define NORETURN     __attribute__((__noreturn__))
58#define PACKED       __attribute__((__packed__))
59#define FORMAT(archetype, string_index, first_to_check) \
60    __attribute__((format(archetype, string_index, first_to_check)))
61#define SECTION(sect) __attribute__((section(sect)))
62#define SENTINEL(param) __attribute__((sentinel(param)))
63#define SENTINEL_LAST __attribute__((sentinel))
64#define UNUSED       __attribute__((__unused__))
65#define USED         __attribute__((__used__))
66#if defined(__clang__) && !__has_attribute(externally_visible)
67  #define VISIBLE /* ignored */
68#else
69  #define VISIBLE __attribute__((__externally_visible__))
70#endif
71#define WARNING(msg) __attribute__((warning(msg)))
72#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
73#define WEAK         __attribute__((weak))
74#define WEAK_ALIAS(to) __attribute__((weak, alias(#to)))
75
76#define CONSTRUCTOR_MIN_PRIORITY 101
77#define CONSTRUCTOR_MAX_PRIORITY 65535
78#define CONSTRUCTOR(priority) __attribute__((constructor(priority)))
79
80/* alloc_align was added to GCC in 4.9 */
81#if __has_attribute(alloc_align) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)))
82#define ALLOC_ALIGN(arg) __attribute__((alloc_align(arg)))
83#else
84#define ALLOC_ALIGN(arg) /* ignored */
85#endif
86
87/* returns_nonnull was added to GCC in 4.9 */
88#if __has_attribute(returns_nonnull) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)))
89#define RETURNS_NONNULL __attribute__((returns_nonnull))
90#else
91#define RETURNS_NONNULL /* ignored */
92#endif
93
94/* A special case for libsel4 so we can avoid depending on this library.
95 * If any other library is caught doing this it will be immolated. */
96#ifndef __LIBSEL4_MACROS_H
97#define PURE         __attribute__((__pure__))
98#define CONST        __attribute__((__const__))
99#endif /* __LIBSEL4_MACROS_H */
100