[llvm] [Support] Add llvm::support::endian::writeNext (PR #88685)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 14 23:18:47 PDT 2024
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/88685
`writeNext` overloads increase the pointer argument like `readNext`.
Code like the following
```
endian::write32<ELFT::Endianness>(p, 42);
p += 4;
endian::write32<ELFT::Endianness>(p, 43);
p += 4;
```
can be simplified to:
```
endian::writeNext<uint32_t, ELFT::Endianness>(p, 42);
endian::writeNext<uint32_t, ELFT::Endianness>(p, 43);
```
>From e4cc675973b042597a06cc90c6f997bc3d76af8a Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sun, 14 Apr 2024 23:18:37 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.5-bogner
---
llvm/include/llvm/Support/Endian.h | 15 +++++++++++++++
llvm/unittests/Support/EndianTest.cpp | 23 +++++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/llvm/include/llvm/Support/Endian.h b/llvm/include/llvm/Support/Endian.h
index 4c0405cf1e2f69..1cdb5ca0d5eaa1 100644
--- a/llvm/include/llvm/Support/Endian.h
+++ b/llvm/include/llvm/Support/Endian.h
@@ -102,6 +102,21 @@ inline void write(void *memory, value_type value) {
write<value_type, alignment>(memory, value, endian);
}
+/// Write a value of a particular endianness, and increment the buffer past that
+/// value.
+template <typename value_type, std::size_t alignment = unaligned,
+ typename CharT>
+inline void writeNext(CharT *&memory, value_type value, endianness endian) {
+ write(memory, value, endian);
+ memory += sizeof(value_type);
+}
+
+template <typename value_type, endianness endian,
+ std::size_t alignment = unaligned, typename CharT>
+inline void writeNext(CharT *&memory, value_type value) {
+ writeNext<value_type, alignment, CharT>(memory, value, endian);
+}
+
template <typename value_type>
using make_unsigned_t = std::make_unsigned_t<value_type>;
diff --git a/llvm/unittests/Support/EndianTest.cpp b/llvm/unittests/Support/EndianTest.cpp
index ab7dfc3800691d..bba1a56168f709 100644
--- a/llvm/unittests/Support/EndianTest.cpp
+++ b/llvm/unittests/Support/EndianTest.cpp
@@ -36,6 +36,29 @@ TEST(Endian, Read) {
1)));
}
+TEST(Endian, WriteNext) {
+ unsigned char bigval[] = {0x00, 0x00}, *p = bigval;
+ endian::writeNext<int16_t, llvm::endianness::big>(p, short(0xaabb));
+ EXPECT_EQ(bigval[0], 0xaa);
+ EXPECT_EQ(bigval[1], 0xbb);
+ EXPECT_EQ(p, bigval + 2);
+
+ char littleval[8] = {}, *q = littleval;
+ endian::writeNext<uint32_t, llvm::endianness::little>(q, 0x44556677);
+ EXPECT_EQ(littleval[0], 0x77);
+ EXPECT_EQ(littleval[1], 0x66);
+ EXPECT_EQ(littleval[2], 0x55);
+ EXPECT_EQ(littleval[3], 0x44);
+ EXPECT_EQ(q, littleval + 4);
+
+ endian::writeNext<uint32_t>(q, 0x11223344, llvm::endianness::little);
+ EXPECT_EQ(littleval[4], 0x44);
+ EXPECT_EQ(littleval[5], 0x33);
+ EXPECT_EQ(littleval[6], 0x22);
+ EXPECT_EQ(littleval[7], 0x11);
+ EXPECT_EQ(q, littleval + 8);
+}
+
TEST(Endian, ReadBitAligned) {
// Simple test to make sure we properly pull out the 0x0 word.
unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};
More information about the llvm-commits
mailing list