]> git.proxmox.com Git - mirror_frr.git/blame - lib/compiler.h
lib/printf: disable wchar_t support
[mirror_frr.git] / lib / compiler.h
CommitLineData
de1a880c
DL
1/*
2 * Copyright (c) 2015-2017 David Lamparter, for NetDEF, Inc.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _FRR_COMPILER_H
18#define _FRR_COMPILER_H
19
5e244469
RW
20#ifdef __cplusplus
21extern "C" {
22#endif
23
de1a880c
DL
24/* function attributes, use like
25 * void prototype(void) __attribute__((_CONSTRUCTOR(100)));
26 */
27#if defined(__clang__)
996c9314 28#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5)
de1a880c 29# define _RET_NONNULL , returns_nonnull
996c9314 30#endif
bd27ea43
DL
31#if __has_attribute(fallthrough)
32# define _FALLTHROUGH __attribute__((fallthrough));
33#endif
de1a880c 34# define _CONSTRUCTOR(x) constructor(x)
bcea0c0f 35# define _DEPRECATED(x) deprecated(x)
de1a880c 36#elif defined(__GNUC__)
996c9314 37#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
de1a880c 38# define _RET_NONNULL , returns_nonnull
996c9314
LB
39#endif
40#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
de1a880c
DL
41# define _CONSTRUCTOR(x) constructor(x)
42# define _DESTRUCTOR(x) destructor(x)
43# define _ALLOC_SIZE(x) alloc_size(x)
996c9314 44#endif
bcea0c0f
DL
45#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
46# define _DEPRECATED(x) deprecated(x)
47#endif
bd27ea43
DL
48#if __GNUC__ >= 7
49# define _FALLTHROUGH __attribute__((fallthrough));
50#endif
de1a880c
DL
51#endif
52
53#ifdef __sun
54/* Solaris doesn't do constructor priorities due to linker restrictions */
996c9314
LB
55#undef _CONSTRUCTOR
56#undef _DESTRUCTOR
de1a880c
DL
57#endif
58
59/* fallback versions */
60#ifndef _RET_NONNULL
61# define _RET_NONNULL
62#endif
63#ifndef _CONSTRUCTOR
64# define _CONSTRUCTOR(x) constructor
65#endif
66#ifndef _DESTRUCTOR
67# define _DESTRUCTOR(x) destructor
68#endif
69#ifndef _ALLOC_SIZE
70# define _ALLOC_SIZE(x)
71#endif
bd27ea43
DL
72#ifndef _FALLTHROUGH
73#define _FALLTHROUGH
74#endif
bcea0c0f
DL
75#ifndef _DEPRECATED
76#define _DEPRECATED(x) deprecated
77#endif
de1a880c 78
3b18b6c0
DL
79/* pure = function does not modify memory & return value is the same if
80 * memory hasn't changed (=> allows compiler to optimize)
81 *
82 * Mostly autodetected by the compiler if function body is available (i.e.
83 * static inline functions in headers). Since that implies it should only be
84 * used in headers for non-inline functions, the "extern" is included here.
85 */
86#define ext_pure extern __attribute__((pure))
87
0d019561
DL
88/* for helper functions defined inside macros */
89#define macro_inline static inline __attribute__((unused))
90#define macro_pure static inline __attribute__((unused, pure))
91
de1a880c
DL
92/*
93 * for warnings on macros, put in the macro content like this:
94 * #define MACRO BLA CPP_WARN("MACRO has been deprecated")
95 */
96#define CPP_STR(X) #X
97
98#if defined(__ICC)
99#define CPP_NOTICE(text) _Pragma(CPP_STR(message __FILE__ ": " text))
100#define CPP_WARN(text) CPP_NOTICE(text)
101
102#elif (defined(__GNUC__) \
103 && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) \
104 || (defined(__clang__) \
105 && (__clang_major__ >= 4 \
106 || (__clang_major__ == 3 && __clang_minor__ >= 5)))
107#define CPP_WARN(text) _Pragma(CPP_STR(GCC warning text))
108#define CPP_NOTICE(text) _Pragma(CPP_STR(message text))
109
110#else
111#define CPP_WARN(text)
ec40eaf9 112#define CPP_NOTICE(text)
de1a880c
DL
113#endif
114
0d019561
DL
115/* MAX / MIN are not commonly defined, but useful */
116/* note: glibc sys/param.h has #define MIN(a,b) (((a)<(b))?(a):(b)) */
117#ifdef MAX
118#undef MAX
119#endif
120#define MAX(a, b) \
121 ({ \
122 typeof(a) _max_a = (a); \
123 typeof(b) _max_b = (b); \
124 _max_a > _max_b ? _max_a : _max_b; \
125 })
126#ifdef MIN
127#undef MIN
128#endif
129#define MIN(a, b) \
130 ({ \
131 typeof(a) _min_a = (a); \
132 typeof(b) _min_b = (b); \
133 _min_a < _min_b ? _min_a : _min_b; \
134 })
135
136#ifndef offsetof
137#ifdef __compiler_offsetof
138#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE,MEMBER)
139#else
140#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
141#endif
142#endif
143
144/* this variant of container_of() retains 'const' on pointers without needing
145 * to be told to do so. The following will all work without warning:
146 *
147 * struct member *p;
148 * const struct member *cp;
149 *
150 * const struct cont *x = container_of(cp, struct cont, member);
151 * const struct cont *x = container_of(cp, const struct cont, member);
152 * const struct cont *x = container_of(p, struct cont, member);
153 * const struct cont *x = container_of(p, const struct cont, member);
154 * struct cont *x = container_of(p, struct cont, member);
155 *
156 * but the following will generate warnings about stripping const:
157 *
158 * struct cont *x = container_of(cp, struct cont, member);
159 * struct cont *x = container_of(cp, const struct cont, member);
160 * struct cont *x = container_of(p, const struct cont, member);
161 */
162#ifdef container_of
163#undef container_of
164#endif
165#define container_of(ptr, type, member) \
166 (__builtin_choose_expr( \
167 __builtin_types_compatible_p(typeof(&((type *)0)->member), \
168 typeof(ptr)) \
169 || __builtin_types_compatible_p(void *, typeof(ptr)), \
170 ({ \
171 typeof(((type *)0)->member) *__mptr = (void *)(ptr); \
172 (type *)((char *)__mptr - offsetof(type, member)); \
173 }), \
174 ({ \
175 typeof(((const type *)0)->member) *__mptr = (ptr); \
176 (const type *)((const char *)__mptr - \
177 offsetof(type, member)); \
178 }) \
179 ))
180
181#define container_of_null(ptr, type, member) \
182 ({ \
183 typeof(ptr) _tmp = (ptr); \
184 _tmp ? container_of(_tmp, type, member) : NULL; \
185 })
186
187#define array_size(ar) (sizeof(ar) / sizeof(ar[0]))
188
5e244469
RW
189#ifdef __cplusplus
190}
191#endif
192
de1a880c 193#endif /* _FRR_COMPILER_H */