xref: /llvm-project/clang/unittests/AST/ByteCode/BitcastBuffer.cpp (revision 12ca72ba7f11fb880794a37cffdea5f47e3062f4)
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 
10 using namespace clang;
11 using namespace clang::interp;
12 
13 TEST(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(Data, &V, sizeof(V));
20 
21   Endian HostEndianness =
22       llvm::sys::IsLittleEndianHost ? Endian::Little : Endian::Big;
23 
24   Buff1.pushData(Data, Bits::zero(), VSize, 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(Bits::zero(), VSize, VSize, Endian::Little);
42     std::memcpy(&V2, D.get(), sizeof(V));
43     ASSERT_EQ(V, V2);
44 
45     D = Buff1.copyBits(Bits::zero(), VSize, VSize, Endian::Big);
46     std::memcpy(&V2, D.get(), sizeof(V));
47     ASSERT_EQ(V, V2);
48   }
49 
50   BitcastBuffer Buff2(Bytes(sizeof(int)).toBits());
51   {
52     short s1 = 0xCAFE;
53     short s2 = 0xBABE;
54     std::byte sdata[2];
55 
56     std::memcpy(sdata, &s1, sizeof(s1));
57     Buff2.pushData(sdata, Bits::zero(), Bits(sizeof(s1) * 8), HostEndianness);
58     std::memcpy(sdata, &s2, sizeof(s2));
59     Buff2.pushData(sdata, Bits(sizeof(s1) * 8), Bits(sizeof(s2) * 8),
60                    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(Bits::zero(), Bits(sizeof(V) * 8),
78                             Bits(sizeof(V) * 8), Endian::Little);
79     std::memcpy(&V, D.get(), sizeof(V));
80     ASSERT_EQ(V, 0xBABECAFE);
81 
82     D = Buff2.copyBits(Bits::zero(), Bits(sizeof(V) * 8), Bits(sizeof(V) * 8),
83                        Endian::Big);
84     std::memcpy(&V, D.get(), sizeof(V));
85     ASSERT_EQ(V, 0xBABECAFE);
86   }
87 }
88