1// If DEFINE_FUNC_ATTRIBUTES macro is not defined then all function attributes
2// are defined as empty values.
3//
4// If DO_NOT_DEFINE_EMPTY_ATTRIBUTES then empty macros are not defined. Thus
5// undefined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES
6// leaves file with untouched FUNC_ATTR_* macros. This variant is used for
7// scripts/gendeclarations.lua.
8//
9// Empty macros are used for *.c files. (undefined DEFINE_FUNC_ATTRIBUTES and
10// undefined DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
11//
12// Macros defined as __attribute__((*)) are used by generated header files.
13// (defined DEFINE_FUNC_ATTRIBUTES and undefined
14// DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
15//
16// Defined DEFINE_FUNC_ATTRIBUTES and defined DO_NOT_DEFINE_EMPTY_ATTRIBUTES is
17// not used by anything.
18
19// FUNC_ATTR_* macros should be in *.c files for declarations generator. If you
20// define a function for which declaration is not generated by
21// gendeclarations.lua (e.g. template hash implementation) then you should use
22// REAL_FATTR_* macros.
23
24// gcc and clang expose their version as follows:
25//
26// gcc 4.7.2:
27// __GNUC__ = 4
28// __GNUC_MINOR__ = 7
29// __GNUC_PATCHLEVEL = 2
30//
31// clang 3.4 (claims compat with gcc 4.2.1):
32// __GNUC__ = 4
33// __GNUC_MINOR__ = 2
34// __GNUC_PATCHLEVEL = 1
35// __clang__ = 1
36// __clang_major__ = 3
37// __clang_minor__ = 4
38//
39// To view the default defines of these compilers, you can perform:
40//
41// $ gcc -E -dM - </dev/null
42// $ echo | clang -dM -E -
43
44#include "nvim/macros.h"
45
46#ifdef FUNC_ATTR_MALLOC
47# undef FUNC_ATTR_MALLOC
48#endif
49
50#ifdef FUNC_ATTR_ALLOC_SIZE
51# undef FUNC_ATTR_ALLOC_SIZE
52#endif
53
54#ifdef FUNC_ATTR_ALLOC_SIZE_PROD
55# undef FUNC_ATTR_ALLOC_SIZE_PROD
56#endif
57
58#ifdef FUNC_ATTR_ALLOC_ALIGN
59# undef FUNC_ATTR_ALLOC_ALIGN
60#endif
61
62#ifdef FUNC_ATTR_PURE
63# undef FUNC_ATTR_PURE
64#endif
65
66#ifdef FUNC_ATTR_CONST
67# undef FUNC_ATTR_CONST
68#endif
69
70#ifdef FUNC_ATTR_WARN_UNUSED_RESULT
71# undef FUNC_ATTR_WARN_UNUSED_RESULT
72#endif
73
74#ifdef FUNC_ATTR_ALWAYS_INLINE
75# undef FUNC_ATTR_ALWAYS_INLINE
76#endif
77
78#ifdef FUNC_ATTR_UNUSED
79# undef FUNC_ATTR_UNUSED
80#endif
81
82#ifdef FUNC_ATTR_NONNULL_ALL
83# undef FUNC_ATTR_NONNULL_ALL
84#endif
85
86#ifdef FUNC_ATTR_NONNULL_ARG
87# undef FUNC_ATTR_NONNULL_ARG
88#endif
89
90#ifdef FUNC_ATTR_NONNULL_RET
91# undef FUNC_ATTR_NONNULL_RET
92#endif
93
94#ifdef FUNC_ATTR_NORETURN
95# undef FUNC_ATTR_NORETURN
96#endif
97
98#ifdef FUNC_ATTR_NO_SANITIZE_UNDEFINED
99# undef FUNC_ATTR_NO_SANITIZE_UNDEFINED
100#endif
101
102#ifdef FUNC_ATTR_PRINTF
103# undef FUNC_ATTR_PRINTF
104#endif
105
106#ifndef DID_REAL_ATTR
107# define DID_REAL_ATTR
108# ifdef __GNUC__
109// For all gnulikes: gcc, clang, intel.
110
111// place these after the argument list of the function declaration
112// (not definition), like so:
113// void myfunc(void) REAL_FATTR_ALWAYS_INLINE;
114# define REAL_FATTR_MALLOC __attribute__((malloc))
115# define REAL_FATTR_ALLOC_ALIGN(x) __attribute__((alloc_align(x)))
116# define REAL_FATTR_PURE __attribute__ ((pure))
117# define REAL_FATTR_CONST __attribute__((const))
118# define REAL_FATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
119# define REAL_FATTR_ALWAYS_INLINE __attribute__((always_inline))
120# define REAL_FATTR_UNUSED __attribute__((unused))
121# define REAL_FATTR_NONNULL_ALL __attribute__((nonnull))
122# define REAL_FATTR_NONNULL_ARG(...) __attribute__((nonnull(__VA_ARGS__)))
123# define REAL_FATTR_NORETURN __attribute__((noreturn))
124# define REAL_FATTR_PRINTF(x, y) __attribute__((format (printf, x, y)))
125
126# if NVIM_HAS_ATTRIBUTE(returns_nonnull)
127# define REAL_FATTR_NONNULL_RET __attribute__((returns_nonnull))
128# endif
129
130# if NVIM_HAS_ATTRIBUTE(alloc_size)
131# define REAL_FATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
132# define REAL_FATTR_ALLOC_SIZE_PROD(x, y) __attribute__((alloc_size(x, y)))
133# endif
134
135# if NVIM_HAS_ATTRIBUTE(no_sanitize_undefined)
136# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
137 __attribute__((no_sanitize_undefined))
138# elif NVIM_HAS_ATTRIBUTE(no_sanitize)
139# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
140 __attribute__((no_sanitize("undefined")))
141# endif
142# endif
143
144// Define attributes that are not defined for this compiler.
145
146# ifndef REAL_FATTR_MALLOC
147# define REAL_FATTR_MALLOC
148# endif
149
150# ifndef REAL_FATTR_ALLOC_SIZE
151# define REAL_FATTR_ALLOC_SIZE(x)
152# endif
153
154# ifndef REAL_FATTR_ALLOC_SIZE_PROD
155# define REAL_FATTR_ALLOC_SIZE_PROD(x, y)
156# endif
157
158# ifndef REAL_FATTR_ALLOC_ALIGN
159# define REAL_FATTR_ALLOC_ALIGN(x)
160# endif
161
162# ifndef REAL_FATTR_PURE
163# define REAL_FATTR_PURE
164# endif
165
166# ifndef REAL_FATTR_CONST
167# define REAL_FATTR_CONST
168# endif
169
170# ifndef REAL_FATTR_WARN_UNUSED_RESULT
171# define REAL_FATTR_WARN_UNUSED_RESULT
172# endif
173
174# ifndef REAL_FATTR_ALWAYS_INLINE
175# define REAL_FATTR_ALWAYS_INLINE
176# endif
177
178# ifndef REAL_FATTR_UNUSED
179# define REAL_FATTR_UNUSED
180# endif
181
182# ifndef REAL_FATTR_NONNULL_ALL
183# define REAL_FATTR_NONNULL_ALL
184# endif
185
186# ifndef REAL_FATTR_NONNULL_ARG
187# define REAL_FATTR_NONNULL_ARG(...)
188# endif
189
190# ifndef REAL_FATTR_NONNULL_RET
191# define REAL_FATTR_NONNULL_RET
192# endif
193
194# ifndef REAL_FATTR_NORETURN
195# define REAL_FATTR_NORETURN
196# endif
197
198# ifndef REAL_FATTR_NO_SANITIZE_UNDEFINED
199# define REAL_FATTR_NO_SANITIZE_UNDEFINED
200# endif
201
202# ifndef REAL_FATTR_PRINTF
203# define REAL_FATTR_PRINTF(x, y)
204# endif
205#endif
206
207#ifdef DEFINE_FUNC_ATTRIBUTES
208/// Fast (non-deferred) API function.
209# define FUNC_API_FAST
210/// Internal C function not exposed in the RPC API.
211# define FUNC_API_NOEXPORT
212/// API function not exposed in VimL/eval.
213# define FUNC_API_REMOTE_ONLY
214/// API function introduced at the given API level.
215# define FUNC_API_SINCE(X)
216/// API function deprecated since the given API level.
217# define FUNC_API_DEPRECATED_SINCE(X)
218# define FUNC_ATTR_MALLOC REAL_FATTR_MALLOC
219# define FUNC_ATTR_ALLOC_SIZE(x) REAL_FATTR_ALLOC_SIZE(x)
220# define FUNC_ATTR_ALLOC_SIZE_PROD(x, y) REAL_FATTR_ALLOC_SIZE_PROD(x, y)
221# define FUNC_ATTR_ALLOC_ALIGN(x) REAL_FATTR_ALLOC_ALIGN(x)
222# define FUNC_ATTR_PURE REAL_FATTR_PURE
223# define FUNC_ATTR_CONST REAL_FATTR_CONST
224# define FUNC_ATTR_WARN_UNUSED_RESULT REAL_FATTR_WARN_UNUSED_RESULT
225# define FUNC_ATTR_ALWAYS_INLINE REAL_FATTR_ALWAYS_INLINE
226# define FUNC_ATTR_UNUSED REAL_FATTR_UNUSED
227# define FUNC_ATTR_NONNULL_ALL REAL_FATTR_NONNULL_ALL
228# define FUNC_ATTR_NONNULL_ARG(...) REAL_FATTR_NONNULL_ARG(__VA_ARGS__)
229# define FUNC_ATTR_NONNULL_RET REAL_FATTR_NONNULL_RET
230# define FUNC_ATTR_NORETURN REAL_FATTR_NORETURN
231# define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED
232# define FUNC_ATTR_PRINTF(x, y) REAL_FATTR_PRINTF(x, y)
233#elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
234# define FUNC_ATTR_MALLOC
235# define FUNC_ATTR_ALLOC_SIZE(x)
236# define FUNC_ATTR_ALLOC_SIZE_PROD(x, y)
237# define FUNC_ATTR_ALLOC_ALIGN(x)
238# define FUNC_ATTR_PURE
239# define FUNC_ATTR_CONST
240# define FUNC_ATTR_WARN_UNUSED_RESULT
241# define FUNC_ATTR_ALWAYS_INLINE
242# define FUNC_ATTR_UNUSED
243# define FUNC_ATTR_NONNULL_ALL
244# define FUNC_ATTR_NONNULL_ARG(...)
245# define FUNC_ATTR_NONNULL_RET
246# define FUNC_ATTR_NORETURN
247# define FUNC_ATTR_NO_SANITIZE_UNDEFINED
248# define FUNC_ATTR_PRINTF(x, y)
249#endif
250