https://github.com/daltenty updated https://github.com/llvm/llvm-project/pull/186032
>From 7701606ef879fd6283e097a0171b505edfa7887b Mon Sep 17 00:00:00 2001 From: David Tenty <[email protected]> Date: Wed, 11 Mar 2026 12:02:23 -0400 Subject: [PATCH 1/3] [clang][Headers] add endian.h POSIX.1-2024 defines a header called `endian.h`` which contains macros and helpers for handling byte order conversions. Unfortunately it is not available on all platforms, however LLVM libc has a useful endian.h implementation that is essentially only casts and builtins. This PR draws on that implementation to add a clang header so applications on platforms without it can make use of this header. The clang header forwards to the system header if available, so existing usages are not affected. --- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/endian.h | 62 ++++++++++++++++++++++++++++++++ clang/test/Headers/endian.c | 40 +++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 clang/lib/Headers/endian.h create mode 100644 clang/test/Headers/endian.c diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 89e582564050b..c6c299bb61af3 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -3,6 +3,7 @@ # to platform specific lists below. set(core_files builtins.h + endian.h float.h __float_float.h __float_header_macro.h diff --git a/clang/lib/Headers/endian.h b/clang/lib/Headers/endian.h new file mode 100644 index 0000000000000..6225baf1127b1 --- /dev/null +++ b/clang/lib/Headers/endian.h @@ -0,0 +1,62 @@ +//===-- Definition of macros from endian.h --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef __CLANG_ENDIAN_H +#define __CLANG_ENDIAN_H + +// If the system has an endian.h, let's use that instead. +#if __STDC_HOSTED__ && __has_include_next(<endian.h>) +# include_next <endian.h> +#else + +#include <stdint.h> + +// Implementation taken from llvm libc endian-macros.h. +#ifdef __cplusplus +#define __CLANG_ENDIAN_CAST(cast, type, value) (cast<type>(value)) +#else +#define __CLANG_ENDIAN_CAST(cast, type, value) ((type)(value)) +#endif + +#define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#define BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#define BYTE_ORDER __BYTE_ORDER__ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define htobe16(x) __builtin_bswap16((x)) +#define htobe32(x) __builtin_bswap32((x)) +#define htobe64(x) __builtin_bswap64((x)) +#define htole16(x) __CLANG_ENDIAN_CAST(static_cast, uint16_t, x) +#define htole32(x) __CLANG_ENDIAN_CAST(static_cast, uint32_t, x) +#define htole64(x) __CLANG_ENDIAN_CAST(static_cast, uint64_t, x) +#define be16toh(x) __builtin_bswap16((x)) +#define be32toh(x) __builtin_bswap32((x)) +#define be64toh(x) __builtin_bswap64((x)) +#define le16toh(x) __CLANG_ENDIAN_CAST(static_cast, uint16_t, x) +#define le32toh(x) __CLANG_ENDIAN_CAST(static_cast, uint32_t, x) +#define le64toh(x) __CLANG_ENDIAN_CAST(static_cast, uint64_t, x) + +#else + +#define htobe16(x) __CLANG_ENDIAN_CAST(static_cast, uint16_t, x) +#define htobe32(x) __CLANG_ENDIAN_CAST(static_cast, uint32_t, x) +#define htobe64(x) __CLANG_ENDIAN_CAST(static_cast, uint64_t, x) +#define htole16(x) __builtin_bswap16((x)) +#define htole32(x) __builtin_bswap32((x)) +#define htole64(x) __builtin_bswap64((x)) +#define be16toh(x) __CLANG_ENDIAN_CAST(static_cast, uint16_t, x) +#define be32toh(x) __CLANG_ENDIAN_CAST(static_cast, uint32_t, x) +#define be64toh(x) __CLANG_ENDIAN_CAST(static_cast, uint64_t, x) +#define le16toh(x) __builtin_bswap16((x)) +#define le32toh(x) __builtin_bswap32((x)) +#define le64toh(x) __builtin_bswap64((x)) + +#endif +#endif // __has_include_next +#endif // __CLANG_ENDIAN_H \ No newline at end of file diff --git a/clang/test/Headers/endian.c b/clang/test/Headers/endian.c new file mode 100644 index 0000000000000..c6fc4e82c6d8d --- /dev/null +++ b/clang/test/Headers/endian.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -triple powerpc64-unknown -fsyntax-only -verify -ffreestanding %s +// RUN: %clang_cc1 -triple ppc64le-unknown -fsyntax-only -verify -xc++ -ffreestanding %s +// expected-no-diagnostics + +#include <endian.h> + + +#if BYTE_ORDER == BIG_ENDIAN + +_Static_assert(htobe16(0xBEEF) == 0xBEEF, ""); +_Static_assert(htobe32(0xDEADBEEF) == 0xDEADBEEF, ""); +_Static_assert(htobe64(0xDEADBEEFDEADBEEF) == 0xDEADBEEFDEADBEEF, ""); +_Static_assert(htole16(0xBEEF) == 0xEFBE, ""); +_Static_assert(htole32(0xDEADBEEF) == 0xEFBEADDE, ""); +_Static_assert(htole64(0xDEADBEEFDEADBEEF) == 0xEFBEADDEEFBEADDE, ""); +_Static_assert(be16toh(0xBEEF) == 0xBEEF, ""); +_Static_assert(be32toh(0xDEADBEEF) == 0xDEADBEEF, ""); +_Static_assert(be64toh(0xDEADBEEFDEADBEEF) == 0xDEADBEEFDEADBEEF, ""); +_Static_assert(le16toh(0xBEEF) == 0xEFBE, ""); +_Static_assert(le32toh(0xDEADBEEF) == 0xEFBEADDE, ""); +_Static_assert(le64toh(0xDEADBEEFDEADBEEF) == 0xEFBEADDEEFBEADDE, ""); + +#elif BYTE_ORDER == LITTLE_ENDIAN + +_Static_assert(htobe16(0xBEEF) == 0xEFBE, ""); +_Static_assert(htobe32(0xDEADBEEF) == 0xEFBEADDE, ""); +_Static_assert(htobe64(0xDEADBEEFDEADBEEF) == 0xEFBEADDEEFBEADDE, ""); +_Static_assert(htole16(0xBEEF) == 0xBEEF, ""); +_Static_assert(htole32(0xDEADBEEF) == 0xDEADBEEF, ""); +_Static_assert(htole64(0xDEADBEEFDEADBEEF) == 0xDEADBEEFDEADBEEF, ""); +_Static_assert(be16toh(0xBEEF) == 0xEFBE, ""); +_Static_assert(be32toh(0xDEADBEEF) == 0xEFBEADDE, ""); +_Static_assert(be64toh(0xDEADBEEFDEADBEEF) == 0xEFBEADDEEFBEADDE, ""); +_Static_assert(le16toh(0xBEEF) == 0xBEEF, ""); +_Static_assert(le32toh(0xDEADBEEF) == 0xDEADBEEF, ""); +_Static_assert(le64toh(0xDEADBEEFDEADBEEF) == 0xDEADBEEFDEADBEEF, ""); + +#else +#error "Invalid byte order" +#endif >From 2ba97d0e1b16ca1f4868dbacb2a06cb994dcd783 Mon Sep 17 00:00:00 2001 From: David Tenty <[email protected]> Date: Thu, 12 Mar 2026 10:10:08 -0400 Subject: [PATCH 2/3] Fix missing new line --- clang/lib/Headers/endian.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Headers/endian.h b/clang/lib/Headers/endian.h index 6225baf1127b1..98e8ea33e4da5 100644 --- a/clang/lib/Headers/endian.h +++ b/clang/lib/Headers/endian.h @@ -59,4 +59,4 @@ #endif #endif // __has_include_next -#endif // __CLANG_ENDIAN_H \ No newline at end of file +#endif // __CLANG_ENDIAN_H >From 86efa0a849332acf8bb816c034f3bbadf470b9d8 Mon Sep 17 00:00:00 2001 From: David Tenty <[email protected]> Date: Thu, 12 Mar 2026 10:11:40 -0400 Subject: [PATCH 3/3] Fix test variations to be both byte orders for both C & C++ --- clang/test/Headers/endian.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/Headers/endian.c b/clang/test/Headers/endian.c index c6fc4e82c6d8d..1f69e599eab19 100644 --- a/clang/test/Headers/endian.c +++ b/clang/test/Headers/endian.c @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -triple powerpc64-unknown -fsyntax-only -verify -ffreestanding %s +// RUN: %clang_cc1 -triple powerpc64-unknown -fsyntax-only -verify -xc++ -ffreestanding %s +// RUN: %clang_cc1 -triple ppc64le-unknown -fsyntax-only -verify -ffreestanding %s // RUN: %clang_cc1 -triple ppc64le-unknown -fsyntax-only -verify -xc++ -ffreestanding %s // expected-no-diagnostics _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
