From 28920aff8f4f1c050f30cc069ed26a69fd335815 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 21 Sep 2017 08:51:08 -0700 Subject: [PATCH] Fix build with clang on big-endian targets (#4440) * flatbuffers: Move EndianSwap template to flatbuffers/base.h Clang complains call to function 'EndianSwap' that is neither visible in the template definition nor found by argument-dependent lookup return EndianSwap(t); This seems to be due to limitation of two-phase lookup of dependent names in template definitions Its not being found using associated namespaces therefore it has to be made visible at the template definition site as well Signed-off-by: Khem Raj * use __builtin_bswap16 when building with clang clang pretends to be gcc 4.2.0 and therefore the code does not use __builtin_bswap16 but tries to synthesize it Signed-off-by: Khem Raj --- include/flatbuffers/base.h | 33 +++++++++++++++++++++++++++++++ include/flatbuffers/flatbuffers.h | 32 ------------------------------ 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index a96c8567e..538784ac8 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -167,6 +167,39 @@ typedef uintmax_t largest_scalar_t; // We support aligning the contents of buffers up to this size. #define FLATBUFFERS_MAX_ALIGNMENT 16 +template T EndianSwap(T t) { + #if defined(_MSC_VER) + #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort + #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong + #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 + #else + #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) + // __builtin_bswap16 was missing prior to GCC 4.8. + #define FLATBUFFERS_BYTESWAP16(x) \ + static_cast(__builtin_bswap32(static_cast(x) << 16)) + #else + #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 + #endif + #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 + #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 + #endif + if (sizeof(T) == 1) { // Compile-time if-then's. + return t; + } else if (sizeof(T) == 2) { + auto r = FLATBUFFERS_BYTESWAP16(*reinterpret_cast(&t)); + return *reinterpret_cast(&r); + } else if (sizeof(T) == 4) { + auto r = FLATBUFFERS_BYTESWAP32(*reinterpret_cast(&t)); + return *reinterpret_cast(&r); + } else if (sizeof(T) == 8) { + auto r = FLATBUFFERS_BYTESWAP64(*reinterpret_cast(&t)); + return *reinterpret_cast(&r); + } else { + assert(0); + } +} + + template T EndianScalar(T t) { #if FLATBUFFERS_LITTLEENDIAN return t; diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index 627f097e3..b7bad5390 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -37,38 +37,6 @@ inline void EndianCheck() { (void)endiantest; } -template T EndianSwap(T t) { - #if defined(_MSC_VER) - #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort - #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong - #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 - #else - #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 - // __builtin_bswap16 was missing prior to GCC 4.8. - #define FLATBUFFERS_BYTESWAP16(x) \ - static_cast(__builtin_bswap32(static_cast(x) << 16)) - #else - #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 - #endif - #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 - #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 - #endif - if (sizeof(T) == 1) { // Compile-time if-then's. - return t; - } else if (sizeof(T) == 2) { - auto r = FLATBUFFERS_BYTESWAP16(*reinterpret_cast(&t)); - return *reinterpret_cast(&r); - } else if (sizeof(T) == 4) { - auto r = FLATBUFFERS_BYTESWAP32(*reinterpret_cast(&t)); - return *reinterpret_cast(&r); - } else if (sizeof(T) == 8) { - auto r = FLATBUFFERS_BYTESWAP64(*reinterpret_cast(&t)); - return *reinterpret_cast(&r); - } else { - assert(0); - } -} - template FLATBUFFERS_CONSTEXPR size_t AlignOf() { #ifdef _MSC_VER return __alignof(T);