1 //===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines several macros, based on the current compiler. This allows 11 // use of compiler-specific features in a way that remains portable. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_SUPPORT_COMPILER_H 16 #define LLVM_SUPPORT_COMPILER_H 17 18 #ifndef __has_feature 19 # define __has_feature(x) 0 20 #endif 21 22 /// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references? 23 /// This implies that <utility> provides the one-argument std::move; it 24 /// does not imply the existence of any other C++ library features. 25 #if (__has_feature(cxx_rvalue_references) \ 26 || defined(__GXX_EXPERIMENTAL_CXX0X__) \ 27 || (defined(_MSC_VER) && _MSC_VER >= 1600)) 28 #define LLVM_USE_RVALUE_REFERENCES 1 29 #else 30 #define LLVM_USE_RVALUE_REFERENCES 0 31 #endif 32 33 /// llvm_move - Expands to ::std::move if the compiler supports 34 /// r-value references; otherwise, expands to the argument. 35 #if LLVM_USE_RVALUE_REFERENCES 36 #define llvm_move(value) (::std::move(value)) 37 #else 38 #define llvm_move(value) (value) 39 #endif 40 41 /// LLVM_DELETED_FUNCTION - Expands to = delete if the compiler supports it. 42 /// Use to mark functions as uncallable. Member functions with this should 43 /// be declared private so that some behaivor is kept in C++03 mode. 44 /// 45 /// class DontCopy { 46 /// private: 47 /// DontCopy(const DontCopy&) LLVM_DELETED_FUNCTION; 48 /// DontCopy &operator =(const DontCopy&) LLVM_DELETED_FUNCTION; 49 /// public: 50 /// ... 51 /// }; 52 #if (__has_feature(cxx_deleted_functions) \ 53 || defined(__GXX_EXPERIMENTAL_CXX0X__)) 54 // No version of MSVC currently supports this. 55 #define LLVM_DELETED_FUNCTION = delete 56 #else 57 #define LLVM_DELETED_FUNCTION 58 #endif 59 60 /// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked 61 /// into a shared library, then the class should be private to the library and 62 /// not accessible from outside it. Can also be used to mark variables and 63 /// functions, making them private to any shared library they are linked into. 64 #if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) 65 #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) 66 #else 67 #define LLVM_LIBRARY_VISIBILITY 68 #endif 69 70 #if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 71 #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) 72 #else 73 #define LLVM_ATTRIBUTE_USED 74 #endif 75 76 // Some compilers warn about unused functions. When a function is sometimes 77 // used or not depending on build settings (e.g. a function only called from 78 // within "assert"), this attribute can be used to suppress such warnings. 79 // 80 // However, it shouldn't be used for unused *variables*, as those have a much 81 // more portable solution: 82 // (void)unused_var_name; 83 // Prefer cast-to-void wherever it is sufficient. 84 #if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 85 #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) 86 #else 87 #define LLVM_ATTRIBUTE_UNUSED 88 #endif 89 90 #if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) 91 #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) 92 #else 93 #define LLVM_ATTRIBUTE_WEAK 94 #endif 95 96 #ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions. 97 #define LLVM_READNONE __attribute__((__const__)) 98 #else 99 #define LLVM_READNONE 100 #endif 101 102 #ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions. 103 #define LLVM_READONLY __attribute__((__pure__)) 104 #else 105 #define LLVM_READONLY 106 #endif 107 108 #if (__GNUC__ >= 4) 109 #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) 110 #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) 111 #else 112 #define LLVM_LIKELY(EXPR) (EXPR) 113 #define LLVM_UNLIKELY(EXPR) (EXPR) 114 #endif 115 116 117 // C++ doesn't support 'extern template' of template specializations. GCC does, 118 // but requires __extension__ before it. In the header, use this: 119 // EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>); 120 // in the .cpp file, use this: 121 // TEMPLATE_INSTANTIATION(class foo<bar>); 122 #ifdef __GNUC__ 123 #define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X 124 #define TEMPLATE_INSTANTIATION(X) template X 125 #else 126 #define EXTERN_TEMPLATE_INSTANTIATION(X) 127 #define TEMPLATE_INSTANTIATION(X) 128 #endif 129 130 // LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, 131 // mark a method "not for inlining". 132 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) 133 #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) 134 #elif defined(_MSC_VER) 135 #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) 136 #else 137 #define LLVM_ATTRIBUTE_NOINLINE 138 #endif 139 140 // LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do 141 // so, mark a method "always inline" because it is performance sensitive. GCC 142 // 3.4 supported this but is buggy in various cases and produces unimplemented 143 // errors, just use it in GCC 4.0 and later. 144 #if __GNUC__ > 3 145 #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) 146 #elif defined(_MSC_VER) 147 #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline 148 #else 149 #define LLVM_ATTRIBUTE_ALWAYS_INLINE 150 #endif 151 152 153 #ifdef __GNUC__ 154 #define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn)) 155 #elif defined(_MSC_VER) 156 #define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn) 157 #else 158 #define LLVM_ATTRIBUTE_NORETURN 159 #endif 160 161 // LLVM_EXTENSION - Support compilers where we have a keyword to suppress 162 // pedantic diagnostics. 163 #ifdef __GNUC__ 164 #define LLVM_EXTENSION __extension__ 165 #else 166 #define LLVM_EXTENSION 167 #endif 168 169 // LLVM_ATTRIBUTE_DEPRECATED(decl, "message") 170 #if __has_feature(attribute_deprecated_with_message) 171 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ 172 decl __attribute__((deprecated(message))) 173 #elif defined(__GNUC__) 174 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ 175 decl __attribute__((deprecated)) 176 #elif defined(_MSC_VER) 177 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ 178 __declspec(deprecated(message)) decl 179 #else 180 # define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ 181 decl 182 #endif 183 184 // LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands 185 // to an expression which states that it is undefined behavior for the 186 // compiler to reach this point. Otherwise is not defined. 187 #if defined(__clang__) || (__GNUC__ > 4) \ 188 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 189 # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() 190 #endif 191 192 // LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression 193 // which causes the program to exit abnormally. 194 #if defined(__clang__) || (__GNUC__ > 4) \ 195 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) 196 # define LLVM_BUILTIN_TRAP __builtin_trap() 197 #else 198 # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 199 #endif 200 201 #endif 202