From e6f7feb7c773dbf942ff9fc97e7df3689b4faf02 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 21 Oct 2014 21:15:45 +0000 Subject: [PATCH] GCC has supported C++11 ref-qualifiers since 4.8.1 This requires incorporating __GNUC_PATCHLEVEL__ into our prerequisite check, and renaming our __GNUC_PREREQ to LLVM_GNUC_PREREQ, since it is now functionally different. Patch by Chilledheart! Differential Revision: http://reviews.llvm.org/D5879 llvm-svn: 220332 --- include/llvm/Support/Compiler.h | 46 +++++++++++++++++-------------- include/llvm/Support/MathExtras.h | 8 +++--- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 66d310133f8..753910f4bbc 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -33,14 +33,19 @@ # define __has_builtin(x) 0 #endif -/// \macro __GNUC_PREREQ -/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available. -#ifndef __GNUC_PREREQ -# if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define __GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +/// \macro LLVM_GNUC_PREREQ +/// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't +/// available. +#ifndef LLVM_GNUC_PREREQ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LLVM_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \ + ((maj) << 20) + ((min) << 10) + (patch)) +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) +# define LLVM_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) # else -# define __GNUC_PREREQ(maj, min) 0 +# define LLVM_GNUC_PREREQ(maj, min, patch) 0 # endif #endif @@ -72,8 +77,7 @@ /// Sadly, this is separate from just r-value reference support because GCC /// implemented everything but this thus far. No release of GCC yet has support /// for this feature so it is enabled with Clang only. -/// FIXME: This should change to a version check when GCC grows support for it. -#if __has_feature(cxx_rvalue_references) +#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1) #define LLVM_HAS_RVALUE_REFERENCE_THIS 1 #else #define LLVM_HAS_RVALUE_REFERENCE_THIS 0 @@ -128,20 +132,20 @@ /// 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. /// On PE/COFF targets, library visibility is the default, so this isn't needed. -#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) && \ +#if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32) #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #else #define LLVM_LIBRARY_VISIBILITY #endif -#if __has_attribute(used) || __GNUC_PREREQ(3, 1) +#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else #define LLVM_ATTRIBUTE_USED #endif -#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4) +#if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0) #define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__)) #else #define LLVM_ATTRIBUTE_UNUSED_RESULT @@ -155,14 +159,14 @@ // more portable solution: // (void)unused_var_name; // Prefer cast-to-void wherever it is sufficient. -#if __has_attribute(unused) || __GNUC_PREREQ(3, 1) +#if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0) #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) #else #define LLVM_ATTRIBUTE_UNUSED #endif // FIXME: Provide this for PE/COFF targets. -#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) && \ +#if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)) #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #else @@ -185,7 +189,7 @@ #define LLVM_READONLY #endif -#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0) #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) #else @@ -208,7 +212,7 @@ /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, /// mark a method "not for inlining". -#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4) +#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) @@ -220,7 +224,7 @@ /// 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 __has_attribute(always_inline) || __GNUC_PREREQ(4, 0) +#if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0) #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline @@ -236,7 +240,7 @@ #define LLVM_ATTRIBUTE_NORETURN #endif -#if __has_attribute(returns_nonnull) || __GNUC_PREREQ(4, 9) +#if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0) #define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) #else #define LLVM_ATTRIBUTE_RETURNS_NONNULL @@ -268,7 +272,7 @@ /// 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 __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5) +#if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #elif defined(_MSC_VER) # define LLVM_BUILTIN_UNREACHABLE __assume(false) @@ -276,7 +280,7 @@ /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression /// which causes the program to exit abnormally. -#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3) +#if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0) # define LLVM_BUILTIN_TRAP __builtin_trap() #else # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 @@ -284,7 +288,7 @@ /// \macro LLVM_ASSUME_ALIGNED /// \brief Returns a pointer with an assumed alignment. -#if __has_builtin(__builtin_assume_aligned) || __GNUC_PREREQ(4, 7) +#if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) #elif defined(LLVM_BUILTIN_UNREACHABLE) // As of today, clang does not support __builtin_assume_aligned. diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index a096cab3b41..9abc57a843c 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -80,7 +80,7 @@ inline std::size_t countTrailingZeros(uint32_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; -#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_ctz(Val); #elif _MSC_VER unsigned long Index; @@ -95,7 +95,7 @@ inline std::size_t countTrailingZeros(uint64_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; -#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_ctzll(Val); #elif _MSC_VER unsigned long Index; @@ -146,7 +146,7 @@ inline std::size_t countLeadingZeros(uint32_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; -#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clz(Val); #elif _MSC_VER unsigned long Index; @@ -161,7 +161,7 @@ inline std::size_t countLeadingZeros(uint64_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; -#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clzll(Val); #elif _MSC_VER unsigned long Index;