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