Imported Upstream version 2.13.2
[platform/upstream/freetype2.git] / include / freetype / internal / compiler-macros.h
1 /****************************************************************************
2  *
3  * internal/compiler-macros.h
4  *
5  *   Compiler-specific macro definitions used internally by FreeType.
6  *
7  * Copyright (C) 2020-2023 by
8  * David Turner, Robert Wilhelm, and Werner Lemberg.
9  *
10  * This file is part of the FreeType project, and may only be used,
11  * modified, and distributed under the terms of the FreeType project
12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
13  * this file you indicate that you have read the license and
14  * understand and accept it fully.
15  *
16  */
17
18 #ifndef INTERNAL_COMPILER_MACROS_H_
19 #define INTERNAL_COMPILER_MACROS_H_
20
21 #include <freetype/config/public-macros.h>
22
23 FT_BEGIN_HEADER
24
25   /* Fix compiler warning with sgi compiler. */
26 #if defined( __sgi ) && !defined( __GNUC__ )
27 #  if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
28 #    pragma set woff 3505
29 #  endif
30 #endif
31
32   /* Fix compiler warning with sgi compiler. */
33 #if defined( __sgi ) && !defined( __GNUC__ )
34 #  if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
35 #    pragma set woff 3505
36 #  endif
37 #endif
38
39   /* Newer compilers warn for fall-through case statements. */
40 #ifndef FALL_THROUGH
41 #  if ( defined( __STDC_VERSION__ ) && __STDC_VERSION__ > 201710L ) || \
42       ( defined( __cplusplus ) && __cplusplus > 201402L )
43 #    define FALL_THROUGH  [[__fallthrough__]]
44 #  elif ( defined( __GNUC__ ) && __GNUC__ >= 7 )       || \
45         ( defined( __clang__ )                      &&    \
46           ( defined( __apple_build_version__ )            \
47               ? __apple_build_version__ >= 12000000       \
48               : __clang_major__ >= 10 ) )
49 #    define FALL_THROUGH  __attribute__(( __fallthrough__ ))
50 #  else
51 #    define FALL_THROUGH  ( (void)0 )
52 #  endif
53 #endif
54
55   /*
56    * When defining a macro that expands to a non-trivial C statement, use
57    * FT_BEGIN_STMNT and FT_END_STMNT to enclose the macro's body.  This
58    * ensures there are no surprises when the macro is invoked in conditional
59    * branches.
60    *
61    * Example:
62    *
63    *   #define  LOG( ... )        \
64    *     FT_BEGIN_STMNT           \
65    *       if ( logging_enabled ) \
66    *         log( __VA_ARGS__ );  \
67    *     FT_END_STMNT
68    */
69 #define FT_BEGIN_STMNT  do {
70 #define FT_END_STMNT    } while ( 0 )
71
72   /*
73    * FT_DUMMY_STMNT expands to an empty C statement.  Useful for
74    * conditionally defined statement macros.
75    *
76    * Example:
77    *
78    *   #ifdef BUILD_CONFIG_LOGGING
79    *   #define  LOG( ... )         \
80    *      FT_BEGIN_STMNT           \
81    *        if ( logging_enabled ) \
82    *          log( __VA_ARGS__ );  \
83    *      FT_END_STMNT
84    *   #else
85    *   #  define LOG( ... )  FT_DUMMY_STMNT
86    *   #endif
87    */
88 #define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
89
90 #ifdef __UINTPTR_TYPE__
91   /*
92    * GCC and Clang both provide a `__UINTPTR_TYPE__` that can be used to
93    * avoid a dependency on `stdint.h`.
94    */
95 #  define FT_UINT_TO_POINTER( x )  (void *)(__UINTPTR_TYPE__)(x)
96 #elif defined( _WIN64 )
97   /* only 64bit Windows uses the LLP64 data model, i.e., */
98   /* 32-bit integers, 64-bit pointers.                   */
99 #  define FT_UINT_TO_POINTER( x )  (void *)(unsigned __int64)(x)
100 #else
101 #  define FT_UINT_TO_POINTER( x )  (void *)(unsigned long)(x)
102 #endif
103
104   /*
105    * Use `FT_TYPEOF( type )` to cast a value to `type`.  This is useful to
106    * suppress signedness compilation warnings in macros.
107    *
108    * Example:
109    *
110    *   #define PAD_( x, n )  ( (x) & ~FT_TYPEOF( x )( (n) - 1 ) )
111    *
112    * (The `typeof` condition is taken from gnulib's `intprops.h` header
113    * file.)
114    */
115 #if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
116       ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
117         defined( __IBM__TYPEOF__ ) )                                 || \
118       ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
119 #define FT_TYPEOF( type )  ( __typeof__ ( type ) )
120 #else
121 #define FT_TYPEOF( type )  /* empty */
122 #endif
123
124   /*
125    * Mark a function declaration as internal to the library.  This ensures
126    * that it will not be exposed by default to client code, and helps
127    * generate smaller and faster code on ELF-based platforms.  Place this
128    * before a function declaration.
129    */
130
131   /* Visual C, mingw */
132 #if defined( _WIN32 )
133 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  /* empty */
134
135   /* gcc, clang */
136 #elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
137 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  \
138           __attribute__(( visibility( "hidden" ) ))
139
140   /* Sun */
141 #elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
142 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  __hidden
143
144 #else
145 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  /* empty */
146 #endif
147
148   /*
149    * FreeType supports compilation of its C sources with a C++ compiler (in
150    * C++ mode); this introduces a number of subtle issues.
151    *
152    * The main one is that a C++ function declaration and its definition must
153    * have the same 'linkage'.  Because all FreeType headers declare their
154    * functions with C linkage (i.e., within an `extern "C" { ... }` block
155    * due to the magic of FT_BEGIN_HEADER and FT_END_HEADER), their
156    * definition in FreeType sources should also be prefixed with `extern
157    * "C"` when compiled in C++ mode.
158    *
159    * The `FT_FUNCTION_DECLARATION` and `FT_FUNCTION_DEFINITION` macros are
160    * provided to deal with this case, as well as `FT_CALLBACK_DEF` and its
161    * siblings below.
162    */
163
164   /*
165    * `FT_FUNCTION_DECLARATION( type )` can be used to write a C function
166    * declaration to ensure it will have C linkage when the library is built
167    * with a C++ compiler.  The parameter is the function's return type, so a
168    * declaration would look like
169    *
170    *    FT_FUNCTION_DECLARATION( int )
171    *    foo( int x );
172    *
173    * NOTE: This requires that all uses are inside of `FT_BEGIN_HEADER ...
174    * FT_END_HEADER` blocks, which guarantees that the declarations have C
175    * linkage when the headers are included by C++ sources.
176    *
177    * NOTE: Do not use directly.  Use `FT_LOCAL`, `FT_BASE`, and `FT_EXPORT`
178    * instead.
179    */
180 #define FT_FUNCTION_DECLARATION( x )  extern x
181
182   /*
183    * Same as `FT_FUNCTION_DECLARATION`, but for function definitions instead.
184    *
185    * NOTE: Do not use directly.  Use `FT_LOCAL_DEF`, `FT_BASE_DEF`, and
186    * `FT_EXPORT_DEF` instead.
187    */
188 #ifdef __cplusplus
189 #define FT_FUNCTION_DEFINITION( x )  extern "C" x
190 #else
191 #define FT_FUNCTION_DEFINITION( x )  x
192 #endif
193
194   /*
195    * Use `FT_LOCAL` and `FT_LOCAL_DEF` to declare and define, respectively,
196    * an internal FreeType function that is only used by the sources of a
197    * single `src/module/` directory.  This ensures that the functions are
198    * turned into static ones at build time, resulting in smaller and faster
199    * code.
200    */
201 #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
202
203 #define FT_LOCAL( x )      static x
204 #define FT_LOCAL_DEF( x )  static x
205
206 #else
207
208 #define FT_LOCAL( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
209                            FT_FUNCTION_DECLARATION( x )
210 #define FT_LOCAL_DEF( x )  FT_FUNCTION_DEFINITION( x )
211
212 #endif  /* FT_MAKE_OPTION_SINGLE_OBJECT */
213
214   /*
215    * Use `FT_LOCAL_ARRAY` and `FT_LOCAL_ARRAY_DEF` to declare and define,
216    * respectively, a constant array that must be accessed from several
217    * sources in the same `src/module/` sub-directory, and which are internal
218    * to the library.
219    */
220 #define FT_LOCAL_ARRAY( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
221                                  extern const x
222 #define FT_LOCAL_ARRAY_DEF( x )  FT_FUNCTION_DEFINITION( const x )
223
224   /*
225    * `Use FT_BASE` and `FT_BASE_DEF` to declare and define, respectively, an
226    * internal library function that is used by more than a single module.
227    */
228 #define FT_BASE( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
229                           FT_FUNCTION_DECLARATION( x )
230 #define FT_BASE_DEF( x )  FT_FUNCTION_DEFINITION( x )
231
232
233   /*
234    * NOTE: Conditionally define `FT_EXPORT_VAR` due to its definition in
235    * `src/smooth/ftgrays.h` to make the header more portable.
236    */
237 #ifndef FT_EXPORT_VAR
238 #define FT_EXPORT_VAR( x )  FT_FUNCTION_DECLARATION( x )
239 #endif
240
241   /*
242    * When compiling FreeType as a DLL or DSO with hidden visibility,
243    * some systems/compilers need a special attribute in front OR after
244    * the return type of function declarations.
245    *
246    * Two macros are used within the FreeType source code to define
247    * exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`.
248    *
249    * - `FT_EXPORT( return_type )`
250    *
251    *   is used in a function declaration, as in
252    *
253    *   ```
254    *     FT_EXPORT( FT_Error )
255    *     FT_Init_FreeType( FT_Library*  alibrary );
256    *   ```
257    *
258    * - `FT_EXPORT_DEF( return_type )`
259    *
260    *   is used in a function definition, as in
261    *
262    *   ```
263    *     FT_EXPORT_DEF( FT_Error )
264    *     FT_Init_FreeType( FT_Library*  alibrary )
265    *     {
266    *       ... some code ...
267    *       return FT_Err_Ok;
268    *     }
269    *   ```
270    *
271    * You can provide your own implementation of `FT_EXPORT` and
272    * `FT_EXPORT_DEF` here if you want.
273    *
274    * To export a variable, use `FT_EXPORT_VAR`.
275    */
276
277   /* See `freetype/config/public-macros.h` for the `FT_EXPORT` definition */
278 #define FT_EXPORT_DEF( x )  FT_FUNCTION_DEFINITION( x )
279
280   /*
281    * The following macros are needed to compile the library with a
282    * C++ compiler and with 16bit compilers.
283    */
284
285   /*
286    * This is special.  Within C++, you must specify `extern "C"` for
287    * functions which are used via function pointers, and you also
288    * must do that for structures which contain function pointers to
289    * assure C linkage -- it's not possible to have (local) anonymous
290    * functions which are accessed by (global) function pointers.
291    *
292    *
293    * FT_CALLBACK_DEF is used to _define_ a callback function,
294    * located in the same source code file as the structure that uses
295    * it.  FT_COMPARE_DEF, in addition, ensures the `cdecl` calling
296    * convention on x86, required by the C library function `qsort`.
297    *
298    * FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare
299    * and define a callback function, respectively, in a similar way
300    * as FT_BASE and FT_BASE_DEF work.
301    *
302    * FT_CALLBACK_TABLE is used to _declare_ a constant variable that
303    * contains pointers to callback functions.
304    *
305    * FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable
306    * that contains pointers to callback functions.
307    *
308    *
309    * Some 16bit compilers have to redefine these macros to insert
310    * the infamous `_cdecl` or `__fastcall` declarations.
311    */
312 #ifdef __cplusplus
313 #define FT_CALLBACK_DEF( x )  extern "C"  x
314 #else
315 #define FT_CALLBACK_DEF( x )  static  x
316 #endif
317
318 #if defined( __GNUC__ ) && defined( __i386__ )
319 #define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x ) __attribute__(( cdecl ))
320 #elif defined( _MSC_VER ) && defined( _M_IX86 )
321 #define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x ) __cdecl
322 #elif defined( __WATCOMC__ ) && __WATCOMC__ >= 1240
323 #define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x ) __watcall
324 #else
325 #define FT_COMPARE_DEF( x )  FT_CALLBACK_DEF( x )
326 #endif
327
328 #define FT_BASE_CALLBACK( x )      FT_FUNCTION_DECLARATION( x )
329 #define FT_BASE_CALLBACK_DEF( x )  FT_FUNCTION_DEFINITION( x )
330
331 #ifndef FT_CALLBACK_TABLE
332 #ifdef __cplusplus
333 #define FT_CALLBACK_TABLE      extern "C"
334 #define FT_CALLBACK_TABLE_DEF  extern "C"
335 #else
336 #define FT_CALLBACK_TABLE      extern
337 #define FT_CALLBACK_TABLE_DEF  /* nothing */
338 #endif
339 #endif /* FT_CALLBACK_TABLE */
340
341 FT_END_HEADER
342
343 #endif  /* INTERNAL_COMPILER_MACROS_H_ */