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_ */ 344