1#include "../../../lib/AST/ByteCode/BitcastBuffer.h"
2#include "clang/AST/ASTContext.h"
3#include "gtest/gtest.h"
4#include <bitset>
5#include <cassert>
6#include <cmath>
7#include <memory>
8#include <string>
9
10using namespace clang;
11using namespace clang::interp;
12
13TEST(BitcastBuffer, PushData) {
14 BitcastBuffer Buff1(Bytes(sizeof(int)).toBits());
15
16 const unsigned V = 0xCAFEBABE;
17 Bits VSize = Bytes(sizeof(V)).toBits();
18 std::byte Data[sizeof(V)];
19 std::memcpy(dest: Data, src: &V, n: sizeof(V));
20
21 Endian HostEndianness =
22 llvm::sys::IsLittleEndianHost ? Endian::Little : Endian::Big;
23
24 Buff1.pushData(In: Data, BitOffset: Bits::zero(), BitWidth: VSize, TargetEndianness: HostEndianness);
25
26 // The buffer is in host-endianness.
27 if (llvm::sys::IsLittleEndianHost) {
28 ASSERT_EQ(Buff1.Data[0], std::byte{0xbe});
29 ASSERT_EQ(Buff1.Data[1], std::byte{0xba});
30 ASSERT_EQ(Buff1.Data[2], std::byte{0xfe});
31 ASSERT_EQ(Buff1.Data[3], std::byte{0xca});
32 } else {
33 ASSERT_EQ(Buff1.Data[0], std::byte{0xca});
34 ASSERT_EQ(Buff1.Data[1], std::byte{0xfe});
35 ASSERT_EQ(Buff1.Data[2], std::byte{0xba});
36 ASSERT_EQ(Buff1.Data[3], std::byte{0xbe});
37 }
38
39 {
40 unsigned V2;
41 auto D = Buff1.copyBits(BitOffset: Bits::zero(), BitWidth: VSize, FullBitWidth: VSize, TargetEndianness: Endian::Little);
42 std::memcpy(dest: &V2, src: D.get(), n: sizeof(V));
43 ASSERT_EQ(V, V2);
44
45 D = Buff1.copyBits(BitOffset: Bits::zero(), BitWidth: VSize, FullBitWidth: VSize, TargetEndianness: Endian::Big);
46 std::memcpy(dest: &V2, src: D.get(), n: sizeof(V));
47 ASSERT_EQ(V, V2);
48 }
49
50 BitcastBuffer Buff2(Bytes(sizeof(int)).toBits());
51 {
52 short s1 = (short)0xCAFE;
53 short s2 = (short)0xBABE;
54 std::byte sdata[2];
55
56 std::memcpy(dest: sdata, src: &s1, n: sizeof(s1));
57 Buff2.pushData(In: sdata, BitOffset: Bits::zero(), BitWidth: Bits(sizeof(s1) * 8), TargetEndianness: HostEndianness);
58 std::memcpy(dest: sdata, src: &s2, n: sizeof(s2));
59 Buff2.pushData(In: sdata, BitOffset: Bits(sizeof(s1) * 8), BitWidth: Bits(sizeof(s2) * 8),
60 TargetEndianness: HostEndianness);
61 }
62
63 if (llvm::sys::IsLittleEndianHost) {
64 ASSERT_EQ(Buff2.Data[0], std::byte{0xfe});
65 ASSERT_EQ(Buff2.Data[1], std::byte{0xca});
66 ASSERT_EQ(Buff2.Data[2], std::byte{0xbe});
67 ASSERT_EQ(Buff2.Data[3], std::byte{0xba});
68 } else {
69 ASSERT_EQ(Buff2.Data[0], std::byte{0xba});
70 ASSERT_EQ(Buff2.Data[1], std::byte{0xbe});
71 ASSERT_EQ(Buff2.Data[2], std::byte{0xca});
72 ASSERT_EQ(Buff2.Data[3], std::byte{0xfe});
73 }
74
75 {
76 unsigned V;
77 auto D = Buff2.copyBits(BitOffset: Bits::zero(), BitWidth: Bits(sizeof(V) * 8),
78 FullBitWidth: Bits(sizeof(V) * 8), TargetEndianness: Endian::Little);
79 std::memcpy(dest: &V, src: D.get(), n: sizeof(V));
80 ASSERT_EQ(V, 0xBABECAFE);
81
82 D = Buff2.copyBits(BitOffset: Bits::zero(), BitWidth: Bits(sizeof(V) * 8), FullBitWidth: Bits(sizeof(V) * 8),
83 TargetEndianness: Endian::Big);
84 std::memcpy(dest: &V, src: D.get(), n: sizeof(V));
85 ASSERT_EQ(V, 0xBABECAFE);
86 }
87}
88

source code of clang/unittests/AST/ByteCode/BitcastBuffer.cpp