Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / config / compiler / clang.hpp
index aab3c61..95ddcbe 100644 (file)
@@ -1,13 +1,28 @@
 // (C) Copyright Douglas Gregor 2010
 //
-//  Use, modification and distribution are subject to the 
-//  Boost Software License, Version 1.0. (See accompanying file 
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 //  See http://www.boost.org for most recent version.
 
 // Clang compiler setup.
 
+#define BOOST_HAS_PRAGMA_ONCE
+
+// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used.
+#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4))
+#   define BOOST_HAS_PRAGMA_DETECT_MISMATCH
+#endif
+
+// When compiling with clang before __has_extension was defined,
+// even if one writes 'defined(__has_extension) && __has_extension(xxx)',
+// clang reports a compiler error. So the only workaround found is:
+
+#ifndef __has_extension
+#define __has_extension __has_feature
+#endif
+
 #if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS)
 #  define BOOST_NO_EXCEPTIONS
 #endif
 #  define BOOST_NO_TYPEID
 #endif
 
-#if defined(__int64)
+#if defined(__int64) && !defined(__GNUC__)
 #  define BOOST_HAS_MS_INT64
 #endif
 
 #define BOOST_HAS_NRVO
 
+// Branch prediction hints
+#if defined(__has_builtin)
+#if __has_builtin(__builtin_expect)
+#define BOOST_LIKELY(x) __builtin_expect(x, 1)
+#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
+#endif
+#endif
+
 // Clang supports "long long" in all compilation modes.
 #define BOOST_HAS_LONG_LONG
 
+//
+// We disable this if the compiler is really nvcc as it
+// doesn't actually support __int128 as of CUDA_VERSION=5000
+// even though it defines __SIZEOF_INT128__.
+// See https://svn.boost.org/trac/boost/ticket/10418
+// Only re-enable this for nvcc if you're absolutely sure
+// of the circumstances under which it's supported:
+//
+#if defined(__SIZEOF_INT128__) && !defined(__CUDACC__)
+#  define BOOST_HAS_INT128
+#endif
+
+
+//
+// Dynamic shared object (DSO) and dynamic-link library (DLL) support
+//
+#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32)
+#  define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default")))
+#  define BOOST_SYMBOL_IMPORT
+#  define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
+#endif
+
+//
+// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through
+// between switch labels.
+//
+#if __cplusplus >= 201103L && defined(__has_warning)
+#  if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
+#    define BOOST_FALLTHROUGH [[clang::fallthrough]]
+#  endif
+#endif
+
 #if !__has_feature(cxx_auto_type)
 #  define BOOST_NO_CXX11_AUTO_DECLARATIONS
 #  define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
 #endif
 
-#if !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
+//
+// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t
+//
+#if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
 #  define BOOST_NO_CXX11_CHAR16_T
 #  define BOOST_NO_CXX11_CHAR32_T
 #endif
 #  define BOOST_NO_CXX11_RAW_LITERALS
 #endif
 
+#if !__has_feature(cxx_reference_qualified_functions)
+#  define BOOST_NO_CXX11_REF_QUALIFIERS
+#endif
+
 #if !__has_feature(cxx_generalized_initializers)
 #  define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
 #endif
 #  define BOOST_NO_CXX11_VARIADIC_TEMPLATES
 #endif
 
-// Clang always supports variadic macros
-// Clang always supports extern templates
+#if !__has_feature(cxx_user_literals)
+#  define BOOST_NO_CXX11_USER_DEFINED_LITERALS
+#endif
+
+#if !(__has_feature(cxx_alignas) || __has_extension(cxx_alignas))
+#  define BOOST_NO_CXX11_ALIGNAS
+#endif
+
+#if !__has_feature(cxx_trailing_return)
+#  define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
+#endif
+
+#if !__has_feature(cxx_inline_namespaces)
+#  define BOOST_NO_CXX11_INLINE_NAMESPACES
+#endif
+
+#if !__has_feature(cxx_override_control)
+#  define BOOST_NO_CXX11_FINAL
+#endif
+
+#if !(__has_feature(cxx_binary_literals) || __has_extension(cxx_binary_literals))
+#  define BOOST_NO_CXX14_BINARY_LITERALS
+#endif
+
+#if !(__has_feature(cxx_decltype_auto) || __has_extension(cxx_decltype_auto))
+#  define BOOST_NO_CXX14_DECLTYPE_AUTO
+#endif
+
+#if !(__has_feature(cxx_aggregate_nsdmi) || __has_extension(cxx_aggregate_nsdmi))
+#  define BOOST_NO_CXX14_AGGREGATE_NSDMI
+#endif
+
+#if !(__has_feature(cxx_init_captures) || __has_extension(cxx_init_captures))
+#  define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
+#endif
+
+#if !(__has_feature(cxx_generic_lambdas) || __has_extension(cxx_generic_lambdas))
+#  define BOOST_NO_CXX14_GENERIC_LAMBDAS
+#endif
+
+// clang < 3.5 has a defect with dependent type, like following.
+//
+//  template <class T>
+//  constexpr typename enable_if<pred<T> >::type foo(T &)
+//  { } // error: no return statement in constexpr function
+//
+// This issue also affects C++11 mode, but C++11 constexpr requires return stmt.
+// Therefore we don't care such case.
+//
+// Note that we can't check Clang version directly as the numbering system changes depending who's
+// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873)
+// so instead verify that we have a feature that was introduced at the same time as working C++14
+// constexpr (generic lambda's in this case):
+//
+#if !__has_feature(cxx_generic_lambdas) \
+  || !(__has_feature(cxx_relaxed_constexpr) || __has_extension(cxx_relaxed_constexpr))
+#  define BOOST_NO_CXX14_CONSTEXPR
+#endif
+
+#if !(__has_feature(cxx_return_type_deduction) || __has_extension(cxx_return_type_deduction))
+#  define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION
+#endif
+
+#if !(__has_feature(cxx_variable_templates) || __has_extension(cxx_variable_templates))
+#  define BOOST_NO_CXX14_VARIABLE_TEMPLATES
+#endif
+
+#if __cplusplus < 201400
+// All versions with __cplusplus above this value seem to support this:
+#  define BOOST_NO_CXX14_DIGIT_SEPARATORS
+#endif
+
+
+// Unused attribute:
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#  define BOOST_ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
 
 #ifndef BOOST_COMPILER
 #  define BOOST_COMPILER "Clang version " __clang_version__