X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FCompiler.h;h=f654f327a923a9d333c781bb82042d1ebd95ad20;hb=5eb301740c4ee5d978535caa917cc004733a7fca;hp=1376e4664c204421f9eb44d987452cbbaadfb1df;hpb=079b6f5ee5c3516b773a3ad71874c14e8ea7479c;p=oota-llvm.git diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 1376e4664c2..f654f327a92 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -15,36 +15,75 @@ #ifndef LLVM_SUPPORT_COMPILER_H #define LLVM_SUPPORT_COMPILER_H -// The VISIBILITY_HIDDEN macro, used for marking classes with the GCC-specific -// visibility("hidden") attribute. +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide r-value references? +/// This implies that provides the one-argument std::move; it +/// does not imply the existence of any other C++ library features. +#if (__has_feature(cxx_rvalue_references) \ + || defined(__GXX_EXPERIMENTAL_CXX0X__) \ + || _MSC_VER >= 1600) +#define LLVM_USE_RVALUE_REFERENCES 1 +#else +#define LLVM_USE_RVALUE_REFERENCES 0 +#endif + +/// llvm_move - Expands to ::std::move if the compiler supports +/// r-value references; otherwise, expands to the argument. +#if LLVM_USE_RVALUE_REFERENCES +#define llvm_move(value) (::std::move(value)) +#else +#define llvm_move(value) (value) +#endif + +/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked +/// into a shared library, then the class should be private to the library and +/// not accessible from outside it. Can also be used to mark variables and +/// functions, making them private to any shared library they are linked into. #if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) -#define VISIBILITY_HIDDEN __attribute__ ((visibility("hidden"))) +#define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #else -#define VISIBILITY_HIDDEN +#define LLVM_LIBRARY_VISIBILITY #endif #if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -#define ATTRIBUTE_USED __attribute__((__used__)) +#define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else -#define ATTRIBUTE_USED +#define LLVM_ATTRIBUTE_USED #endif +// Some compilers warn about unused functions. When a function is sometimes +// used or not depending on build settings (e.g. a function only called from +// within "assert"), this attribute can be used to suppress such warnings. +// +// However, it shouldn't be used for unused *variables*, as those have a much +// more portable solution: +// (void)unused_var_name; +// Prefer cast-to-void wherever it is sufficient. #if (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -#define ATTRIBUTE_UNUSED __attribute__((__unused__)) +#define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#else +#define LLVM_ATTRIBUTE_UNUSED +#endif + +#if (__GNUC__ >= 4) && !defined(__MINGW32__) && !defined(__CYGWIN__) +#define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #else -#define ATTRIBUTE_UNUSED +#define LLVM_ATTRIBUTE_WEAK #endif -#ifdef __GNUC__ // aka 'ATTRIBUTE_CONST' but following LLVM Conventions. -#define ATTRIBUTE_READNONE __attribute__((__const__)) +#ifdef __GNUC__ // aka 'CONST' but following LLVM Conventions. +#define LLVM_READNONE __attribute__((__const__)) #else -#define ATTRIBUTE_READNONE +#define LLVM_READNONE #endif -#ifdef __GNUC__ // aka 'ATTRIBUTE_PURE' but following LLVM Conventions. -#define ATTRIBUTE_READONLY __attribute__((__pure__)) +#ifdef __GNUC__ // aka 'PURE' but following LLVM Conventions. +#define LLVM_READONLY __attribute__((__pure__)) #else -#define ATTRIBUTE_READONLY +#define LLVM_READONLY #endif #if (__GNUC__ >= 4) @@ -53,6 +92,7 @@ #define BUILTIN_EXPECT(EXPR, VALUE) (EXPR) #endif + // C++ doesn't support 'extern template' of template specializations. GCC does, // but requires __extension__ before it. In the header, use this: // EXTERN_TEMPLATE_INSTANTIATION(class foo); @@ -66,32 +106,66 @@ #define TEMPLATE_INSTANTIATION(X) #endif -// DISABLE_INLINE - On compilers where we have a directive to do so, mark a -// method "not for inlining". +// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, +// mark a method "not for inlining". #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define DISABLE_INLINE __attribute__((noinline)) +#define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) -#define DISABLE_INLINE __declspec(noinline) +#define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) #else -#define DISABLE_INLINE +#define LLVM_ATTRIBUTE_NOINLINE #endif -// ALWAYS_INLINE - On compilers where we have a directive to do so, mark a -// method "always inline" because it is performance sensitive. -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define ALWAYS_INLINE __attribute__((always_inline)) +// LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do +// so, mark a method "always inline" because it is performance sensitive. GCC +// 3.4 supported this but is buggy in various cases and produces unimplemented +// errors, just use it in GCC 4.0 and later. +#if __GNUC__ > 3 +#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) +#elif defined(_MSC_VER) +#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline #else -// TODO: No idea how to do this with MSVC. -#define ALWAYS_INLINE +#define LLVM_ATTRIBUTE_ALWAYS_INLINE #endif #ifdef __GNUC__ -#define NORETURN __attribute__((noreturn)) +#define LLVM_ATTRIBUTE_NORETURN __attribute__((noreturn)) #elif defined(_MSC_VER) -#define NORETURN __declspec(noreturn) +#define LLVM_ATTRIBUTE_NORETURN __declspec(noreturn) +#else +#define LLVM_ATTRIBUTE_NORETURN +#endif + +// LLVM_EXTENSION - Support compilers where we have a keyword to suppress +// pedantic diagnostics. +#ifdef __GNUC__ +#define LLVM_EXTENSION __extension__ #else -#define NORETURN +#define LLVM_EXTENSION +#endif + +// LLVM_ATTRIBUTE_DEPRECATED(decl, "message") +#if __has_feature(attribute_deprecated_with_message) +# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ + decl __attribute__((deprecated(message))) +#elif defined(__GNUC__) +# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ + decl __attribute__((deprecated)) +#elif defined(_MSC_VER) +# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ + __declspec(deprecated(message)) decl +#else +# define LLVM_ATTRIBUTE_DEPRECATED(decl, message) \ + decl +#endif + +// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands +// to an expression which states that it is undefined behavior for the +// compiler to reach this point. Otherwise is not defined. +#if defined(__clang__) || (__GNUC__ > 4) \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #endif #endif