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