1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */ 2 /* ***** BEGIN LICENSE BLOCK ***** 3 * This file is part of openfx-supportext <https://github.com/devernay/openfx-supportext>, 4 * Copyright (C) 2013-2018 INRIA 5 * 6 * openfx-supportext is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * openfx-supportext is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with openfx-supportext. If not, see <http://www.gnu.org/licenses/gpl-2.0.html> 18 * ***** END LICENSE BLOCK ***** */ 19 20 /* 21 * Useful macros. 22 */ 23 24 #ifndef openfx_supportext_ofxsMacros_h 25 #define openfx_supportext_ofxsMacros_h 26 27 /* *INDENT-OFF* */ 28 29 #define OFXS_NAMESPACE_OFX_ENTER namespace OFX { 30 #define OFXS_NAMESPACE_OFX_EXIT } 31 32 // anonymous namespace macros, mainly to avoid crazy intentation by some IDEs (e.g. Xcode) 33 #define OFXS_NAMESPACE_ANONYMOUS_ENTER namespace { 34 #define OFXS_NAMESPACE_ANONYMOUS_EXIT } 35 36 // compiler_warning.h 37 #define STRINGISE_IMPL(x) # x 38 #define STRINGISE(x) STRINGISE_IMPL(x) 39 40 // Use: #pragma message WARN("My message") 41 #if _MSC_VER 42 # define FILE_LINE_LINK __FILE__ "(" STRINGISE(__LINE__) ") : " 43 # define WARN(exp) (FILE_LINE_LINK "WARNING: " exp) 44 #else //__GNUC__ - may need other defines for different compilers 45 # define WARN(exp) ("WARNING: " exp) 46 #endif 47 48 // The following was grabbed from WTF/wtf/Compiler.h (where WTF was replaced by OFXS) 49 50 /* COMPILER() - the compiler being used to build the project */ 51 #define COMPILER(OFXS_FEATURE) (defined OFXS_COMPILER_ ## OFXS_FEATURE && OFXS_COMPILER_ ## OFXS_FEATURE) 52 53 /* COMPILER_SUPPORTS() - whether the compiler being used to build the project supports the given feature. */ 54 #define COMPILER_SUPPORTS(OFXS_COMPILER_FEATURE) (defined OFXS_COMPILER_SUPPORTS_ ## OFXS_COMPILER_FEATURE && OFXS_COMPILER_SUPPORTS_ ## OFXS_COMPILER_FEATURE) 55 56 /* COMPILER_QUIRK() - whether the compiler being used to build the project requires a given quirk. */ 57 #define COMPILER_QUIRK(OFXS_COMPILER_QUIRK) (defined OFXS_COMPILER_QUIRK_ ## OFXS_COMPILER_QUIRK && OFXS_COMPILER_QUIRK_ ## OFXS_COMPILER_QUIRK) 58 59 /* ==== COMPILER() - the compiler being used to build the project ==== */ 60 61 /* COMPILER(CLANG) - Clang */ 62 #if defined(__clang__) 63 #define OFXS_COMPILER_CLANG 1 64 65 #ifndef __has_extension 66 #define __has_extension __has_feature /* Compatibility with older versions of clang */ 67 #endif 68 69 #define CLANG_PRAGMA(PRAGMA) _Pragma(PRAGMA) 70 71 /* Specific compiler features */ 72 #define OFXS_COMPILER_SUPPORTS_CXX_VARIADIC_TEMPLATES __has_extension(cxx_variadic_templates) 73 74 /* There is a bug in clang that comes with Xcode 4.2 where AtomicStrings can't be implicitly converted to Strings 75 in the presence of move constructors and/or move assignment operators. This bug has been fixed in Xcode 4.3 clang, so we 76 check for both cxx_rvalue_references as well as the unrelated cxx_nonstatic_member_init feature which we know was added in 4.3 */ 77 #define OFXS_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES __has_extension(cxx_rvalue_references) && __has_extension(cxx_nonstatic_member_init) 78 79 #define OFXS_COMPILER_SUPPORTS_CXX_DELETED_FUNCTIONS __has_extension(cxx_deleted_functions) 80 #define OFXS_SUPPORTS_CXX_NULLPTR __has_feature(cxx_nullptr) 81 #define OFXS_COMPILER_SUPPORTS_CXX_EXPLICIT_CONVERSIONS __has_feature(cxx_explicit_conversions) 82 #define OFXS_COMPILER_SUPPORTS_BLOCKS __has_feature(blocks) 83 #define OFXS_COMPILER_SUPPORTS_C_STATIC_ASSERT __has_extension(c_static_assert) 84 #define OFXS_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL __has_extension(cxx_override_control) 85 #define OFXS_COMPILER_SUPPORTS_HAS_TRIVIAL_DESTRUCTOR __has_extension(has_trivial_destructor) 86 87 #endif 88 89 #ifndef CLANG_PRAGMA 90 #define CLANG_PRAGMA(PRAGMA) 91 #endif 92 93 /* COMPILER(MSVC) - Microsoft Visual C++ */ 94 /* COMPILER(MSVC7_OR_LOWER) - Microsoft Visual C++ 2003 or lower*/ 95 /* COMPILER(MSVC9_OR_LOWER) - Microsoft Visual C++ 2008 or lower*/ 96 #if defined(_MSC_VER) 97 #define OFXS_COMPILER_MSVC 1 98 #if _MSC_VER < 1400 99 #define OFXS_COMPILER_MSVC7_OR_LOWER 1 100 #elif _MSC_VER < 1600 101 #define OFXS_COMPILER_MSVC9_OR_LOWER 1 102 #endif 103 104 /* Specific compiler features */ 105 #if !COMPILER(CLANG) && _MSC_VER >= 1600 106 #define OFXS_SUPPORTS_CXX_NULLPTR 1 107 #endif 108 109 #if !COMPILER(CLANG) 110 #define OFXS_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL 1 111 #define OFXS_COMPILER_QUIRK_FINAL_IS_CALLED_SEALED 1 112 #endif 113 114 #endif 115 116 /* COMPILER(RVCT) - ARM RealView Compilation Tools */ 117 /* COMPILER(RVCT4_OR_GREATER) - ARM RealView Compilation Tools 4.0 or greater */ 118 #if defined(__CC_ARM) || defined(__ARMCC__) 119 #define OFXS_COMPILER_RVCT 1 120 #define RVCT_VERSION_AT_LEAST(major, minor, patch, build) ( __ARMCC_VERSION >= (major * 100000 + minor * 10000 + patch * 1000 + build) ) 121 #else 122 /* Define this for !RVCT compilers, just so we can write things like RVCT_VERSION_AT_LEAST(3, 0, 0, 0). */ 123 #define RVCT_VERSION_AT_LEAST(major, minor, patch, build) 0 124 #endif 125 126 /* COMPILER(GCCE) - GNU Compiler Collection for Embedded */ 127 #if defined(__GCCE__) 128 #define OFXS_COMPILER_GCCE 1 129 #define GCCE_VERSION (__GCCE__ * 10000 + __GCCE_MINOR__ * 100 + __GCCE_PATCHLEVEL__) 130 #define GCCE_VERSION_AT_LEAST(major, minor, patch) ( GCCE_VERSION >= (major * 10000 + minor * 100 + patch) ) 131 #endif 132 133 /* COMPILER(GCC) - GNU Compiler Collection */ 134 /* --gnu option of the RVCT compiler also defines __GNUC__ */ 135 #if defined(__GNUC__) && !COMPILER(RVCT) 136 #define OFXS_COMPILER_GCC 1 137 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 138 #define GCC_VERSION_AT_LEAST(major, minor, patch) ( GCC_VERSION >= (major * 10000 + minor * 100 + patch) ) 139 #else 140 /* Define this for !GCC compilers, just so we can write things like GCC_VERSION_AT_LEAST(4, 1, 0). */ 141 #define GCC_VERSION_AT_LEAST(major, minor, patch) 0 142 #endif 143 144 /* Specific compiler features */ 145 #if COMPILER(GCC) && !COMPILER(CLANG) 146 #if GCC_VERSION_AT_LEAST(4, 7, 0) && defined(__cplusplus) && __cplusplus >= 201103L 147 #define OFXS_COMPILER_SUPPORTS_CXX_RVALUE_REFERENCES 1 148 #define OFXS_COMPILER_SUPPORTS_CXX_DELETED_FUNCTIONS 1 149 #define OFXS_SUPPORTS_CXX_NULLPTR 1 150 #define OFXS_COMPILER_SUPPORTS_CXX_OVERRIDE_CONTROL 1 151 #define OFXS_COMPILER_QUIRK_GCC11_GLOBAL_ISINF_ISNAN 1 152 153 #elif GCC_VERSION_AT_LEAST(4, 6, 0) && defined(__GXX_EXPERIMENTAL_CXX0X__) 154 #define OFXS_SUPPORTS_CXX_NULLPTR 1 155 #define OFXS_COMPILER_QUIRK_GCC11_GLOBAL_ISINF_ISNAN 1 156 #endif 157 158 #endif 159 160 /* COMPILER(MINGW) - MinGW GCC */ 161 /* COMPILER(MINGW64) - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */ 162 #if defined(__MINGW32__) 163 #define OFXS_COMPILER_MINGW 1 164 #include <_mingw.h> /* private MinGW header */ 165 #if defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */ 166 #define OFXS_COMPILER_MINGW64 1 167 #endif /* __MINGW64_VERSION_MAJOR */ 168 #endif /* __MINGW32__ */ 169 170 /* COMPILER(INTEL) - Intel C++ Compiler */ 171 #if defined(__INTEL_COMPILER) 172 #define OFXS_COMPILER_INTEL 1 173 #endif 174 175 /* COMPILER(SUNCC) */ 176 #if defined(__SUNPRO_CC) || defined(__SUNPRO_C) 177 #define OFXS_COMPILER_SUNCC 1 178 #endif 179 180 /* ==== Compiler features ==== */ 181 182 183 /* ALWAYS_INLINE */ 184 185 #ifndef ALWAYS_INLINE 186 #if COMPILER(GCC) && defined(NDEBUG) && !COMPILER(MINGW) 187 #define ALWAYS_INLINE inline __attribute__( (__always_inline__) ) 188 #elif (COMPILER(MSVC) || COMPILER(RVCT ) ) && defined(NDEBUG) 189 #define ALWAYS_INLINE __forceinline 190 #else 191 #define ALWAYS_INLINE inline 192 #endif 193 #endif 194 195 196 /* NEVER_INLINE */ 197 198 #ifndef NEVER_INLINE 199 #if COMPILER(GCC) 200 #define NEVER_INLINE __attribute__( (__noinline__) ) 201 #elif COMPILER(RVCT) 202 #define NEVER_INLINE __declspec(noinline) 203 #else 204 #define NEVER_INLINE 205 #endif 206 #endif 207 208 209 /* UNLIKELY */ 210 211 #ifndef UNLIKELY 212 #if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(3, 0, 0, 0) && defined(__GNUC__ ) ) 213 #define UNLIKELY(x) __builtin_expect( (x), 0 ) 214 #else 215 #define UNLIKELY(x) (x) 216 #endif 217 #endif 218 219 220 /* LIKELY */ 221 222 #ifndef LIKELY 223 #if COMPILER(GCC) || (RVCT_VERSION_AT_LEAST(3, 0, 0, 0) && defined(__GNUC__ ) ) 224 #define LIKELY(x) __builtin_expect( (x), 1 ) 225 #else 226 #define LIKELY(x) (x) 227 #endif 228 #endif 229 230 231 /* NO_RETURN */ 232 233 234 #ifndef NO_RETURN 235 #if COMPILER(GCC) 236 #define NO_RETURN __attribute( (__noreturn__) ) 237 #elif COMPILER(MSVC) || COMPILER(RVCT) 238 #define NO_RETURN __declspec(noreturn) 239 #else 240 #define NO_RETURN 241 #endif 242 #endif 243 244 245 /* NO_RETURN_WITH_VALUE */ 246 247 #ifndef NO_RETURN_WITH_VALUE 248 #if !COMPILER(MSVC) 249 #define NO_RETURN_WITH_VALUE NO_RETURN 250 #else 251 #define NO_RETURN_WITH_VALUE 252 #endif 253 #endif 254 255 256 /* WARN_UNUSED_RETURN */ 257 258 #if COMPILER(GCC) 259 #define WARN_UNUSED_RETURN __attribute__ ( (warn_unused_result) ) 260 #else 261 #define WARN_UNUSED_RETURN 262 #endif 263 264 /* OVERRIDE and FINAL */ 265 266 #if COMPILER_SUPPORTS(CXX_OVERRIDE_CONTROL) && !COMPILER(MSVC) //< patch so msvc 2010 ignores the override and final keywords. 267 #define OVERRIDE override 268 269 #if COMPILER_QUIRK(FINAL_IS_CALLED_SEALED) 270 #define FINAL sealed 271 #else 272 #define FINAL final 273 #endif 274 275 #else 276 #define OVERRIDE 277 #define FINAL 278 #endif 279 280 /* REFERENCED_FROM_ASM */ 281 282 #ifndef REFERENCED_FROM_ASM 283 #if COMPILER(GCC) 284 #define REFERENCED_FROM_ASM __attribute__( (used) ) 285 #else 286 #define REFERENCED_FROM_ASM 287 #endif 288 #endif 289 290 /* OBJC_CLASS */ 291 292 #ifndef OBJC_CLASS 293 #ifdef __OBJC__ 294 #define OBJC_CLASS @class 295 #else 296 #define OBJC_CLASS class 297 #endif 298 #endif 299 300 /* ABI */ 301 #if defined(__ARM_EABI__) || defined(__EABI__) 302 #define OFXS_COMPILER_SUPPORTS_EABI 1 303 #endif 304 305 // Warning control from https://svn.boost.org/trac/boost/wiki/Guidelines/WarningsGuidelines 306 #if ( ( __GNUC__ * 100) + __GNUC_MINOR__) >= 402 307 #define GCC_DIAG_STR(s) # s 308 #define GCC_DIAG_JOINSTR(x,y) GCC_DIAG_STR(x ## y) 309 # define GCC_DIAG_DO_PRAGMA(x) _Pragma ( # x) 310 # define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x) 311 # if ( ( __GNUC__ * 100) + __GNUC_MINOR__) >= 406 312 # define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \ 313 GCC_DIAG_PRAGMA( ignored GCC_DIAG_JOINSTR(-W,x) ) 314 # define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop) 315 # else 316 # define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA( ignored GCC_DIAG_JOINSTR(-W,x) ) 317 # define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA( warning GCC_DIAG_JOINSTR(-W,x) ) 318 # endif 319 #else 320 # define GCC_DIAG_OFF(x) 321 # define GCC_DIAG_ON(x) 322 #endif 323 324 #ifdef __clang__ 325 # define CLANG_DIAG_STR(s) # s 326 // stringize s to "no-unused-variable" 327 # define CLANG_DIAG_JOINSTR(x,y) CLANG_DIAG_STR(x ## y) 328 // join -W with no-unused-variable to "-Wno-unused-variable" 329 # define CLANG_DIAG_DO_PRAGMA(x) _Pragma ( # x) 330 // _Pragma is unary operator #pragma ("") 331 # define CLANG_DIAG_PRAGMA(x) CLANG_DIAG_DO_PRAGMA(clang diagnostic x) 332 # define CLANG_DIAG_OFF(x) CLANG_DIAG_PRAGMA(push) \ 333 CLANG_DIAG_PRAGMA( ignored CLANG_DIAG_JOINSTR(-W,x) ) 334 // For example: #pragma clang diagnostic ignored "-Wno-unused-variable" 335 # define CLANG_DIAG_ON(x) CLANG_DIAG_PRAGMA(pop) 336 // For example: #pragma clang diagnostic warning "-Wno-unused-variable" 337 #else // Ensure these macros so nothing for other compilers. 338 # define CLANG_DIAG_OFF(x) 339 # define CLANG_DIAG_ON(x) 340 # define CLANG_DIAG_PRAGMA(x) 341 #endif 342 343 /* Usage: 344 CLANG_DIAG_OFF(unused-variable) 345 CLANG_DIAG_OFF(unused-parameter) 346 CLANG_DIAG_OFF(uninitialized) 347 */ 348 349 #if COMPILER_SUPPORTS(CXX_OVERRIDE_CONTROL) 350 // we want to use override & final, and get no warnings even if not compiling in c++11 mode 351 CLANG_DIAG_OFF(c++11-extensions) 352 //GCC_DIAG_OFF(c++11-extensions) // no corresponding GCC warning option? 353 #endif 354 355 /* *INDENT-ON* */ 356 357 #endif // ifndef openfx_supportext_ofxsMacros_h 358