ICU-20784 Do not override clang compiler internal builtins

In the case several internal builtins defined by clang were not available,
ICU was replacing them by a stub implementation. But that was breaking
detection of availability of same methods in other parts of Chromium
(specifically in base/location.h).

Instead of that, this change creates ICU specific macros that will
map to those builtins when available, or to stub implementation if
not.

I.e. for the case of __has_builtin, previous implementation was
defining __has_builtin(x) as 0 in case it was not declared. With
new implementation, there is a macro UPRV_HAS_BUILTIN that maps
to __has_builtin if available, or 0 if not.
This commit is contained in:
Jose Dapena Paz 2019-07-25 16:41:56 +02:00 committed by Markus Scherer
parent d3315d98ef
commit 407442dec7

View file

@ -424,26 +424,40 @@
#endif
/* Compatibility with compilers other than clang: http://clang.llvm.org/docs/LanguageExtensions.html */
#ifndef __has_attribute
# define __has_attribute(x) 0
#ifdef __has_attribute
# define UPRV_HAS_ATTRIBUTE(x) __has_attribute(x)
#else
# define UPRV_HAS_ATTRIBUTE(x) 0
#endif
#ifndef __has_cpp_attribute
# define __has_cpp_attribute(x) 0
#ifdef __has_cpp_attribute
# define UPRV_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
#else
# define UPRV_HAS_CPP_ATTRIBUTE(x) 0
#endif
#ifndef __has_declspec_attribute
# define __has_declspec_attribute(x) 0
#ifdef __has_declspec_attribute
# define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) __has_declspec_attribute(x)
#else
# define UPRV_HAS_DECLSPEC_ATTRIBUTE(x) 0
#endif
#ifndef __has_builtin
# define __has_builtin(x) 0
#ifdef __has_builtin
# define UPRV_HAS_BUILTIN(x) __has_builtin(x)
#else
# define UPRV_HAS_BUILTIN(x) 0
#endif
#ifndef __has_feature
# define __has_feature(x) 0
#ifdef __has_feature
# define UPRV_HAS_FEATURE(x) __has_feature(x)
#else
# define UPRV_HAS_FEATURE(x) 0
#endif
#ifndef __has_extension
# define __has_extension(x) 0
#ifdef __has_extension
# define UPRV_HAS_EXTENSION(x) __has_extension(x)
#else
# define UPRV_HAS_EXTENSION(x) 0
#endif
#ifndef __has_warning
# define __has_warning(x) 0
#ifdef __has_warning
# define UPRV_HAS_WARNING(x) __has_warning(x)
#else
# define UPRV_HAS_WARNING(x) 0
#endif
/**
@ -462,7 +476,9 @@
* Attribute to specify the size of the allocated buffer for malloc-like functions
* @internal
*/
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || __has_attribute(alloc_size)
#if (defined(__GNUC__) && \
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
UPRV_HAS_ATTRIBUTE(alloc_size)
# define U_ALLOC_SIZE_ATTR(X) __attribute__ ((alloc_size(X)))
# define U_ALLOC_SIZE_ATTR2(X,Y) __attribute__ ((alloc_size(X,Y)))
#else
@ -526,8 +542,9 @@ namespace std {
#elif defined(__clang__)
// Test for compiler vs. feature separately.
// Other compilers might choke on the feature test.
# if __has_cpp_attribute(clang::fallthrough) || \
(__has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough"))
# if UPRV_HAS_CPP_ATTRIBUTE(clang::fallthrough) || \
(UPRV_HAS_FEATURE(cxx_attributes) && \
UPRV_HAS_WARNING("-Wimplicit-fallthrough"))
# define U_FALLTHROUGH [[clang::fallthrough]]
# endif
#elif defined(__GNUC__) && (__GNUC__ >= 7)
@ -797,7 +814,8 @@ namespace std {
/* Use the predefined value. */
#elif defined(U_STATIC_IMPLEMENTATION)
# define U_EXPORT
#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
# define U_EXPORT __declspec(dllexport)
#elif defined(__GNUC__)
# define U_EXPORT __attribute__((visibility("default")))
@ -821,7 +839,8 @@ namespace std {
#ifdef U_IMPORT
/* Use the predefined value. */
#elif defined(_MSC_VER) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
#elif defined(_MSC_VER) || (UPRV_HAS_DECLSPEC_ATTRIBUTE(dllexport) && \
UPRV_HAS_DECLSPEC_ATTRIBUTE(dllimport))
/* Windows needs to export/import data. */
# define U_IMPORT __declspec(dllimport)
#else