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