/**************************************************************************** * * internal/compiler-macros.h * * Compiler-specific macro definitions used internally by FreeType. * * Copyright (C) 2020 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used, * modified, and distributed under the terms of the FreeType project * license, LICENSE.TXT. By continuing to use, modify, or distribute * this file you indicate that you have read the license and * understand and accept it fully. * */ #ifndef INTERNAL_COMPILER_MACROS_H_ #define INTERNAL_COMPILER_MACROS_H_ #include FT_BEGIN_HEADER /* Fix compiler warning with sgi compiler. */ #if defined( __sgi ) && !defined( __GNUC__ ) # if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) # pragma set woff 3505 # endif #endif /* Fix compiler warning with sgi compiler. */ #if defined( __sgi ) && !defined( __GNUC__ ) # if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) # pragma set woff 3505 # endif #endif /* * When defining a macro that expands to a non-trivial C statement, use * FT_BEGIN_STMNT and FT_END_STMNT to enclose the macro's body. This * ensures there are no surprises when the macro is invoked in conditional * branches. * * Example: * * #define LOG( ... ) \ * FT_BEGIN_STMNT \ * if ( logging_enabled ) \ * log( __VA_ARGS__ ); \ * FT_END_STMNT */ #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) /* * FT_DUMMY_STMNT expands to an empty C statement. Useful for * conditionally defined statement macros. * * Example: * * #ifdef BUILD_CONFIG_LOGGING * #define LOG( ... ) \ * FT_BEGIN_STMNT \ * if ( logging_enabled ) \ * log( __VA_ARGS__ ); \ * FT_END_STMNT * #else * # define LOG( ... ) FT_DUMMY_STMNT * #endif */ #define FT_DUMMY_STMNT FT_BEGIN_STMNT FT_END_STMNT #ifdef _WIN64 /* only 64bit Windows uses the LLP64 data model, i.e., */ /* 32-bit integers, 64-bit pointers. */ #define FT_UINT_TO_POINTER( x ) (void *)(unsigned __int64)(x) #else #define FT_UINT_TO_POINTER( x ) (void *)(unsigned long)(x) #endif /* * Use `FT_TYPEOF( type )` to cast a value to `type`. This is useful to * suppress signedness compilation warnings in macros. * * Example: * * #define PAD_( x, n ) ( (x) & ~FT_TYPEOF( x )( (n) - 1 ) ) * * (The `typeof` condition is taken from gnulib's `intprops.h` header * file.) */ #if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 ) || \ ( defined( __IBMC__ ) && __IBMC__ >= 1210 && \ defined( __IBM__TYPEOF__ ) ) || \ ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) ) #define FT_TYPEOF( type ) ( __typeof__ ( type ) ) #else #define FT_TYPEOF( type ) /* empty */ #endif /* * Mark a function declaration as internal to the library. This ensures * that it will not be exposed by default to client code, and helps * generate smaller and faster code on ELF-based platforms. Place this * before a function declaration. */ /* Visual C, mingw */ #if defined( _WIN32 ) #define FT_INTERNAL_FUNCTION_ATTRIBUTE /* empty */ /* gcc, clang */ #elif ( defined( __GNUC__ ) && __GNUC__ >= 4 ) || defined( __clang__ ) #define FT_INTERNAL_FUNCTION_ATTRIBUTE \ __attribute__(( visibility( "hidden" ) )) /* Sun */ #elif defined( __SUNPRO_C ) && __SUNPRO_C >= 0x550 #define FT_INTERNAL_FUNCTION_ATTRIBUTE __hidden #else #define FT_INTERNAL_FUNCTION_ATTRIBUTE /* empty */ #endif /* * FreeType supports compilation of its C sources with a C++ compiler (in * C++ mode); this introduces a number of subtle issues. * * The main one is that a C++ function declaration and its definition must * have the same 'linkage'. Because all FreeType headers declare their * functions with C linkage (i.e., within an `extern "C" { ... }` block * due to the magic of FT_BEGIN_HEADER and FT_END_HEADER), their * definition in FreeType sources should also be prefixed with `extern * "C"` when compiled in C++ mode. * * The `FT_FUNCTION_DECLARATION` and `FT_FUNCTION_DEFINITION` macros are * provided to deal with this case, as well as `FT_CALLBACK_DEF` and its * siblings below. */ /* * `FT_FUNCTION_DECLARATION( type )` can be used to write a C function * declaration to ensure it will have C linkage when the library is built * with a C++ compiler. The parameter is the function's return type, so a * declaration would look like * * FT_FUNCTION_DECLARATION( int ) * foo( int x ); * * NOTE: This requires that all uses are inside of `FT_BEGIN_HEADER ... * FT_END_HEADER` blocks, which guarantees that the declarations have C * linkage when the headers are included by C++ sources. * * NOTE: Do not use directly. Use `FT_LOCAL`, `FT_BASE`, and `FT_EXPORT` * instead. */ #define FT_FUNCTION_DECLARATION( x ) extern x /* * Same as `FT_FUNCTION_DECLARATION`, but for function definitions instead. * * NOTE: Do not use directly. Use `FT_LOCAL_DEF`, `FT_BASE_DEF`, and * `FT_EXPORT_DEF` instead. */ #ifdef __cplusplus #define FT_FUNCTION_DEFINITION( x ) extern "C" x #else #define FT_FUNCTION_DEFINITION( x ) x #endif /* * Use `FT_LOCAL` and `FT_LOCAL_DEF` to declare and define, respectively, * an internal FreeType function that is only used by the sources of a * single `src/module/` directory. This ensures that the functions are * turned into static ones at build time, resulting in smaller and faster * code. */ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x #define FT_LOCAL_DEF( x ) static x #else #define FT_LOCAL( x ) FT_INTERNAL_FUNCTION_ATTRIBUTE \ FT_FUNCTION_DECLARATION( x ) #define FT_LOCAL_DEF( x ) FT_FUNCTION_DEFINITION( x ) #endif /* FT_MAKE_OPTION_SINGLE_OBJECT */ /* * Use `FT_LOCAL_ARRAY` and `FT_LOCAL_ARRAY_DEF` to declare and define, * respectively, a constant array that must be accessed from several * sources in the same `src/module/` sub-directory, and which are internal * to the library. */ #define FT_LOCAL_ARRAY( x ) FT_INTERNAL_FUNCTION_ATTRIBUTE \ extern const x #define FT_LOCAL_ARRAY_DEF( x ) FT_FUNCTION_DEFINITION( const x ) /* * `Use FT_BASE` and `FT_BASE_DEF` to declare and define, respectively, an * internal library function that is used by more than a single module. */ #define FT_BASE( x ) FT_INTERNAL_FUNCTION_ATTRIBUTE \ FT_FUNCTION_DECLARATION( x ) #define FT_BASE_DEF( x ) FT_FUNCTION_DEFINITION( x ) /* * NOTE: Conditionally define `FT_EXPORT_VAR` due to its definition in * `src/smooth/ftgrays.h` to make the header more portable. */ #ifndef FT_EXPORT_VAR #define FT_EXPORT_VAR( x ) FT_FUNCTION_DECLARATION( x ) #endif /* When compiling FreeType as a DLL or DSO with hidden visibility, */ /* some systems/compilers need a special attribute in front OR after */ /* the return type of function declarations. */ /* */ /* Two macros are used within the FreeType source code to define */ /* exported library functions: `FT_EXPORT` and `FT_EXPORT_DEF`. */ /* */ /* - `FT_EXPORT( return_type )` */ /* */ /* is used in a function declaration, as in */ /* */ /* ``` */ /* FT_EXPORT( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ); */ /* ``` */ /* */ /* - `FT_EXPORT_DEF( return_type )` */ /* */ /* is used in a function definition, as in */ /* */ /* ``` */ /* FT_EXPORT_DEF( FT_Error ) */ /* FT_Init_FreeType( FT_Library* alibrary ) */ /* { */ /* ... some code ... */ /* return FT_Err_Ok; */ /* } */ /* ``` */ /* */ /* You can provide your own implementation of `FT_EXPORT` and */ /* `FT_EXPORT_DEF` here if you want. */ /* */ /* To export a variable, use `FT_EXPORT_VAR`. */ /* */ /* See `freetype/config/compiler_macros.h` for the `FT_EXPORT` definition */ #define FT_EXPORT_DEF( x ) FT_FUNCTION_DEFINITION( x ) /* The following macros are needed to compile the library with a */ /* C++ compiler and with 16bit compilers. */ /* */ /* This is special. Within C++, you must specify `extern "C"` for */ /* functions which are used via function pointers, and you also */ /* must do that for structures which contain function pointers to */ /* assure C linkage -- it's not possible to have (local) anonymous */ /* functions which are accessed by (global) function pointers. */ /* */ /* */ /* FT_CALLBACK_DEF is used to _define_ a callback function, */ /* located in the same source code file as the structure that uses */ /* it. */ /* */ /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare */ /* and define a callback function, respectively, in a similar way */ /* as FT_BASE and FT_BASE_DEF work. */ /* */ /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ /* contains pointers to callback functions. */ /* */ /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable */ /* that contains pointers to callback functions. */ /* */ /* */ /* Some 16bit compilers have to redefine these macros to insert */ /* the infamous `_cdecl` or `__fastcall` declarations. */ /* */ #ifdef __cplusplus #define FT_CALLBACK_DEF( x ) extern "C" x #else #define FT_CALLBACK_DEF( x ) static x #endif #define FT_BASE_CALLBACK( x ) FT_FUNCTION_DECLARATION( x ) #define FT_BASE_CALLBACK_DEF( x ) FT_FUNCTION_DEFINITION( x ) #ifndef FT_CALLBACK_TABLE #ifdef __cplusplus #define FT_CALLBACK_TABLE extern "C" #define FT_CALLBACK_TABLE_DEF extern "C" #else #define FT_CALLBACK_TABLE extern #define FT_CALLBACK_TABLE_DEF /* nothing */ #endif #endif /* FT_CALLBACK_TABLE */ FT_END_HEADER #endif /* INTERNAL_COMPILER_MACROS_H_ */