• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * internal/compiler-macros.h
4  *
5  *   Compiler-specific macro definitions used internally by FreeType.
6  *
7  * Copyright (C) 2020 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   /*
40    * When defining a macro that expands to a non-trivial C statement, use
41    * FT_BEGIN_STMNT and FT_END_STMNT to enclose the macro's body.  This
42    * ensures there are no surprises when the macro is invoked in conditional
43    * branches.
44    *
45    * Example:
46    *
47    *   #define  LOG( ... )        \
48    *     FT_BEGIN_STMNT           \
49    *       if ( logging_enabled ) \
50    *         log( __VA_ARGS__ );  \
51    *     FT_END_STMNT
52    */
53 #define FT_BEGIN_STMNT  do {
54 #define FT_END_STMNT    } while ( 0 )
55 
56   /*
57    * FT_DUMMY_STMNT expands to an empty C statement.  Useful for
58    * conditionally defined statement macros.
59    *
60    * Example:
61    *
62    *   #ifdef BUILD_CONFIG_LOGGING
63    *   #define  LOG( ... )         \
64    *      FT_BEGIN_STMNT           \
65    *        if ( logging_enabled ) \
66    *          log( __VA_ARGS__ );  \
67    *      FT_END_STMNT
68    *   #else
69    *   #  define LOG( ... )  FT_DUMMY_STMNT
70    *   #endif
71    */
72 #define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
73 
74 #ifdef _WIN64
75   /* only 64bit Windows uses the LLP64 data model, i.e., */
76   /* 32-bit integers, 64-bit pointers.                   */
77 #define FT_UINT_TO_POINTER( x )  (void *)(unsigned __int64)(x)
78 #else
79 #define FT_UINT_TO_POINTER( x )  (void *)(unsigned long)(x)
80 #endif
81 
82   /*
83    * Use `FT_TYPEOF( type )` to cast a value to `type`.  This is useful to
84    * suppress signedness compilation warnings in macros.
85    *
86    * Example:
87    *
88    *   #define PAD_( x, n )  ( (x) & ~FT_TYPEOF( x )( (n) - 1 ) )
89    *
90    * (The `typeof` condition is taken from gnulib's `intprops.h` header
91    * file.)
92    */
93 #if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 )                       || \
94       ( defined( __IBMC__ ) && __IBMC__ >= 1210 &&                      \
95         defined( __IBM__TYPEOF__ ) )                                 || \
96       ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) )
97 #define FT_TYPEOF( type )  ( __typeof__ ( type ) )
98 #else
99 #define FT_TYPEOF( type )  /* empty */
100 #endif
101 
102   /*
103    * Mark a function declaration as internal to the library.  This ensures
104    * that it will not be exposed by default to client code, and helps
105    * generate smaller and faster code on ELF-based platforms.  Place this
106    * before a function declaration.
107    */
108 
109   /* Visual C, mingw */
110 #if defined( _WIN32 )
111 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  /* empty */
112 
113   /* gcc, clang */
114 #elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ )
115 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  \
116           __attribute__(( visibility( "hidden" ) ))
117 
118   /* Sun */
119 #elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550
120 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  __hidden
121 
122 #else
123 #define FT_INTERNAL_FUNCTION_ATTRIBUTE  /* empty */
124 #endif
125 
126   /*
127    * FreeType supports compilation of its C sources with a C++ compiler (in
128    * C++ mode); this introduces a number of subtle issues.
129    *
130    * The main one is that a C++ function declaration and its definition must
131    * have the same 'linkage'.  Because all FreeType headers declare their
132    * functions with C linkage (i.e., within an `extern "C" { ... }` block
133    * due to the magic of FT_BEGIN_HEADER and FT_END_HEADER), their
134    * definition in FreeType sources should also be prefixed with `extern
135    * "C"` when compiled in C++ mode.
136    *
137    * The `FT_FUNCTION_DECLARATION` and `FT_FUNCTION_DEFINITION` macros are
138    * provided to deal with this case, as well as `FT_CALLBACK_DEF` and its
139    * siblings below.
140    */
141 
142   /*
143    * `FT_FUNCTION_DECLARATION( type )` can be used to write a C function
144    * declaration to ensure it will have C linkage when the library is built
145    * with a C++ compiler.  The parameter is the function's return type, so a
146    * declaration would look like
147    *
148    *    FT_FUNCTION_DECLARATION( int )
149    *    foo( int x );
150    *
151    * NOTE: This requires that all uses are inside of `FT_BEGIN_HEADER ...
152    * FT_END_HEADER` blocks, which guarantees that the declarations have C
153    * linkage when the headers are included by C++ sources.
154    *
155    * NOTE: Do not use directly.  Use `FT_LOCAL`, `FT_BASE`, and `FT_EXPORT`
156    * instead.
157    */
158 #define FT_FUNCTION_DECLARATION( x )  extern x
159 
160   /*
161    * Same as `FT_FUNCTION_DECLARATION`, but for function definitions instead.
162    *
163    * NOTE: Do not use directly.  Use `FT_LOCAL_DEF`, `FT_BASE_DEF`, and
164    * `FT_EXPORT_DEF` instead.
165    */
166 #ifdef __cplusplus
167 #define FT_FUNCTION_DEFINITION( x )  extern "C" x
168 #else
169 #define FT_FUNCTION_DEFINITION( x )  x
170 #endif
171 
172   /*
173    * Use `FT_LOCAL` and `FT_LOCAL_DEF` to declare and define, respectively,
174    * an internal FreeType function that is only used by the sources of a
175    * single `src/module/` directory.  This ensures that the functions are
176    * turned into static ones at build time, resulting in smaller and faster
177    * code.
178    */
179 #ifdef FT_MAKE_OPTION_SINGLE_OBJECT
180 
181 #define FT_LOCAL( x )      static x
182 #define FT_LOCAL_DEF( x )  static x
183 
184 #else
185 
186 #define FT_LOCAL( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
187                            FT_FUNCTION_DECLARATION( x )
188 #define FT_LOCAL_DEF( x )  FT_FUNCTION_DEFINITION( x )
189 
190 #endif  /* FT_MAKE_OPTION_SINGLE_OBJECT */
191 
192   /*
193    * Use `FT_LOCAL_ARRAY` and `FT_LOCAL_ARRAY_DEF` to declare and define,
194    * respectively, a constant array that must be accessed from several
195    * sources in the same `src/module/` sub-directory, and which are internal
196    * to the library.
197    */
198 #define FT_LOCAL_ARRAY( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
199                                  extern const x
200 #define FT_LOCAL_ARRAY_DEF( x )  FT_FUNCTION_DEFINITION( const x )
201 
202   /*
203    * `Use FT_BASE` and `FT_BASE_DEF` to declare and define, respectively, an
204    * internal library function that is used by more than a single module.
205    */
206 #define FT_BASE( x )      FT_INTERNAL_FUNCTION_ATTRIBUTE \
207                           FT_FUNCTION_DECLARATION( x )
208 #define FT_BASE_DEF( x )  FT_FUNCTION_DEFINITION( x )
209 
210 
211   /*
212    * NOTE: Conditionally define `FT_EXPORT_VAR` due to its definition in
213    * `src/smooth/ftgrays.h` to make the header more portable.
214    */
215 #ifndef FT_EXPORT_VAR
216 #define FT_EXPORT_VAR( x )  FT_FUNCTION_DECLARATION( x )
217 #endif
218 
219   /* When compiling FreeType as a DLL or DSO with hidden visibility,   */
220   /* some systems/compilers need a special attribute in front OR after */
221   /* the return type of function declarations.                         */
222   /*                                                                   */
223   /* Two macros are used within the FreeType source code to define     */
224   /* exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`.      */
225   /*                                                                   */
226   /* - `FT_EXPORT( return_type )`                                      */
227   /*                                                                   */
228   /*   is used in a function declaration, as in                        */
229   /*                                                                   */
230   /*   ```                                                             */
231   /*     FT_EXPORT( FT_Error )                                         */
232   /*     FT_Init_FreeType( FT_Library*  alibrary );                    */
233   /*   ```                                                             */
234   /*                                                                   */
235   /* - `FT_EXPORT_DEF( return_type )`                                  */
236   /*                                                                   */
237   /*   is used in a function definition, as in                         */
238   /*                                                                   */
239   /*   ```                                                             */
240   /*     FT_EXPORT_DEF( FT_Error )                                     */
241   /*     FT_Init_FreeType( FT_Library*  alibrary )                     */
242   /*     {                                                             */
243   /*       ... some code ...                                           */
244   /*       return FT_Err_Ok;                                           */
245   /*     }                                                             */
246   /*   ```                                                             */
247   /*                                                                   */
248   /* You can provide your own implementation of `FT_EXPORT` and        */
249   /* `FT_EXPORT_DEF` here if you want.                                 */
250   /*                                                                   */
251   /* To export a variable, use `FT_EXPORT_VAR`.                        */
252   /*                                                                   */
253 
254   /* See `freetype/config/compiler_macros.h` for the `FT_EXPORT` definition */
255 #define FT_EXPORT_DEF( x )  FT_FUNCTION_DEFINITION( x )
256 
257   /* The following macros are needed to compile the library with a   */
258   /* C++ compiler and with 16bit compilers.                          */
259   /*                                                                 */
260 
261   /* This is special.  Within C++, you must specify `extern "C"` for */
262   /* functions which are used via function pointers, and you also    */
263   /* must do that for structures which contain function pointers to  */
264   /* assure C linkage -- it's not possible to have (local) anonymous */
265   /* functions which are accessed by (global) function pointers.     */
266   /*                                                                 */
267   /*                                                                 */
268   /* FT_CALLBACK_DEF is used to _define_ a callback function,        */
269   /* located in the same source code file as the structure that uses */
270   /* it.                                                             */
271   /*                                                                 */
272   /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare   */
273   /* and define a callback function, respectively, in a similar way  */
274   /* as FT_BASE and FT_BASE_DEF work.                                */
275   /*                                                                 */
276   /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
277   /* contains pointers to callback functions.                        */
278   /*                                                                 */
279   /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
280   /* that contains pointers to callback functions.                   */
281   /*                                                                 */
282   /*                                                                 */
283   /* Some 16bit compilers have to redefine these macros to insert    */
284   /* the infamous `_cdecl` or `__fastcall` declarations.             */
285   /*                                                                 */
286 #ifdef __cplusplus
287 #define FT_CALLBACK_DEF( x )  extern "C"  x
288 #else
289 #define FT_CALLBACK_DEF( x )  static  x
290 #endif
291 
292 #define FT_BASE_CALLBACK( x )      FT_FUNCTION_DECLARATION( x )
293 #define FT_BASE_CALLBACK_DEF( x )  FT_FUNCTION_DEFINITION( x )
294 
295 #ifndef FT_CALLBACK_TABLE
296 #ifdef __cplusplus
297 #define FT_CALLBACK_TABLE      extern "C"
298 #define FT_CALLBACK_TABLE_DEF  extern "C"
299 #else
300 #define FT_CALLBACK_TABLE      extern
301 #define FT_CALLBACK_TABLE_DEF  /* nothing */
302 #endif
303 #endif /* FT_CALLBACK_TABLE */
304 
305 FT_END_HEADER
306 
307 #endif  /* INTERNAL_COMPILER_MACROS_H_ */
308