xref: /aosp_15_r20/external/llvm/unittests/Bitcode/BitstreamReaderTest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/BitstreamReader.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/BitstreamWriter.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/StreamingMemoryObject.h"
14*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker using namespace llvm;
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker namespace {
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker class BufferStreamer : public DataStreamer {
21*9880d681SAndroid Build Coastguard Worker   StringRef Buffer;
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker public:
BufferStreamer(StringRef Buffer)24*9880d681SAndroid Build Coastguard Worker   BufferStreamer(StringRef Buffer) : Buffer(Buffer) {}
GetBytes(unsigned char * OutBuffer,size_t Length)25*9880d681SAndroid Build Coastguard Worker   size_t GetBytes(unsigned char *OutBuffer, size_t Length) override {
26*9880d681SAndroid Build Coastguard Worker     if (Length >= Buffer.size())
27*9880d681SAndroid Build Coastguard Worker       Length = Buffer.size();
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker     std::copy(Buffer.begin(), Buffer.begin() + Length, OutBuffer);
30*9880d681SAndroid Build Coastguard Worker     Buffer = Buffer.drop_front(Length);
31*9880d681SAndroid Build Coastguard Worker     return Length;
32*9880d681SAndroid Build Coastguard Worker   }
33*9880d681SAndroid Build Coastguard Worker };
34*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,AtEndOfStream)35*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, AtEndOfStream) {
36*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[4] = {
37*9880d681SAndroid Build Coastguard Worker     0x00, 0x01, 0x02, 0x03
38*9880d681SAndroid Build Coastguard Worker   };
39*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
40*9880d681SAndroid Build Coastguard Worker   BitstreamCursor Cursor(Reader);
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(Cursor.AtEndOfStream());
43*9880d681SAndroid Build Coastguard Worker   (void)Cursor.Read(8);
44*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(Cursor.AtEndOfStream());
45*9880d681SAndroid Build Coastguard Worker   (void)Cursor.Read(24);
46*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(Cursor.AtEndOfStream());
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   Cursor.JumpToBit(0);
49*9880d681SAndroid Build Coastguard Worker   EXPECT_FALSE(Cursor.AtEndOfStream());
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   Cursor.JumpToBit(32);
52*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(Cursor.AtEndOfStream());
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,AtEndOfStreamJump)55*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, AtEndOfStreamJump) {
56*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[4] = {
57*9880d681SAndroid Build Coastguard Worker     0x00, 0x01, 0x02, 0x03
58*9880d681SAndroid Build Coastguard Worker   };
59*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
60*9880d681SAndroid Build Coastguard Worker   BitstreamCursor Cursor(Reader);
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker   Cursor.JumpToBit(32);
63*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(Cursor.AtEndOfStream());
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,AtEndOfStreamEmpty)66*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
67*9880d681SAndroid Build Coastguard Worker   uint8_t Dummy = 0xFF;
68*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(&Dummy, &Dummy);
69*9880d681SAndroid Build Coastguard Worker   BitstreamCursor Cursor(Reader);
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(Cursor.AtEndOfStream());
72*9880d681SAndroid Build Coastguard Worker }
73*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,getCurrentByteNo)74*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, getCurrentByteNo) {
75*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
76*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
77*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = 33; I != E; ++I) {
80*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
81*9880d681SAndroid Build Coastguard Worker     (void)Cursor.Read(1);
82*9880d681SAndroid Build Coastguard Worker   }
83*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(4u, Cursor.getCurrentByteNo());
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,getPointerToByte)86*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, getPointerToByte) {
87*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
88*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
89*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = 8; I != E; ++I) {
92*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(Bytes + I, Cursor.getPointerToByte(I, 1));
93*9880d681SAndroid Build Coastguard Worker   }
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,getPointerToBit)96*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, getPointerToBit) {
97*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
98*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
99*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = 8; I != E; ++I) {
102*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(Bytes + I, Cursor.getPointerToBit(I * 8, 1));
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,jumpToPointer)106*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, jumpToPointer) {
107*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
108*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
109*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   for (unsigned I : {0, 6, 2, 7}) {
112*9880d681SAndroid Build Coastguard Worker     Cursor.jumpToPointer(Bytes + I);
113*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(I, Cursor.getCurrentByteNo());
114*9880d681SAndroid Build Coastguard Worker   }
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,setArtificialByteLimit)117*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, setArtificialByteLimit) {
118*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
119*9880d681SAndroid Build Coastguard Worker                      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
120*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
121*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker   Cursor.setArtificialByteLimit(8);
124*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(8u, Cursor.getSizeIfKnown());
125*9880d681SAndroid Build Coastguard Worker   while (!Cursor.AtEndOfStream())
126*9880d681SAndroid Build Coastguard Worker     (void)Cursor.Read(1);
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(8u, Cursor.getCurrentByteNo());
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,setArtificialByteLimitNotWordBoundary)131*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, setArtificialByteLimitNotWordBoundary) {
132*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
133*9880d681SAndroid Build Coastguard Worker                      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
134*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
135*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
136*9880d681SAndroid Build Coastguard Worker 
137*9880d681SAndroid Build Coastguard Worker   Cursor.setArtificialByteLimit(5);
138*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(8u, Cursor.getSizeIfKnown());
139*9880d681SAndroid Build Coastguard Worker   while (!Cursor.AtEndOfStream())
140*9880d681SAndroid Build Coastguard Worker     (void)Cursor.Read(1);
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(8u, Cursor.getCurrentByteNo());
143*9880d681SAndroid Build Coastguard Worker }
144*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,setArtificialByteLimitPastTheEnd)145*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEnd) {
146*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
147*9880d681SAndroid Build Coastguard Worker                      0x08, 0x09, 0x0a, 0x0b};
148*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
149*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   // The size of the memory object isn't known yet.  Set it too high and
152*9880d681SAndroid Build Coastguard Worker   // confirm that we don't read too far.
153*9880d681SAndroid Build Coastguard Worker   Cursor.setArtificialByteLimit(24);
154*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(24u, Cursor.getSizeIfKnown());
155*9880d681SAndroid Build Coastguard Worker   while (!Cursor.AtEndOfStream())
156*9880d681SAndroid Build Coastguard Worker     (void)Cursor.Read(1);
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(12u, Cursor.getCurrentByteNo());
159*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(12u, Cursor.getSizeIfKnown());
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,setArtificialByteLimitPastTheEndKnown)162*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEndKnown) {
163*9880d681SAndroid Build Coastguard Worker   uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
164*9880d681SAndroid Build Coastguard Worker                      0x08, 0x09, 0x0a, 0x0b};
165*9880d681SAndroid Build Coastguard Worker   BitstreamReader Reader(std::begin(Bytes), std::end(Bytes));
166*9880d681SAndroid Build Coastguard Worker   SimpleBitstreamCursor Cursor(Reader);
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker   // Save the size of the memory object in the cursor.
169*9880d681SAndroid Build Coastguard Worker   while (!Cursor.AtEndOfStream())
170*9880d681SAndroid Build Coastguard Worker     (void)Cursor.Read(1);
171*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(12u, Cursor.getCurrentByteNo());
172*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(12u, Cursor.getSizeIfKnown());
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker   Cursor.setArtificialByteLimit(20);
175*9880d681SAndroid Build Coastguard Worker   EXPECT_TRUE(Cursor.AtEndOfStream());
176*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(12u, Cursor.getSizeIfKnown());
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
TEST(BitstreamReaderTest,readRecordWithBlobWhileStreaming)179*9880d681SAndroid Build Coastguard Worker TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
180*9880d681SAndroid Build Coastguard Worker   SmallVector<uint8_t, 1> BlobData;
181*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, E = 1024; I != E; ++I)
182*9880d681SAndroid Build Coastguard Worker     BlobData.push_back(I);
183*9880d681SAndroid Build Coastguard Worker 
184*9880d681SAndroid Build Coastguard Worker   // Try a bunch of different sizes.
185*9880d681SAndroid Build Coastguard Worker   const unsigned Magic = 0x12345678;
186*9880d681SAndroid Build Coastguard Worker   const unsigned BlockID = bitc::FIRST_APPLICATION_BLOCKID;
187*9880d681SAndroid Build Coastguard Worker   const unsigned RecordID = 1;
188*9880d681SAndroid Build Coastguard Worker   for (unsigned I = 0, BlobSize = 0, E = BlobData.size(); BlobSize < E;
189*9880d681SAndroid Build Coastguard Worker        BlobSize += ++I) {
190*9880d681SAndroid Build Coastguard Worker     StringRef BlobIn((const char *)BlobData.begin(), BlobSize);
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker     // Write the bitcode.
193*9880d681SAndroid Build Coastguard Worker     SmallVector<char, 1> Buffer;
194*9880d681SAndroid Build Coastguard Worker     unsigned AbbrevID;
195*9880d681SAndroid Build Coastguard Worker     {
196*9880d681SAndroid Build Coastguard Worker       BitstreamWriter Stream(Buffer);
197*9880d681SAndroid Build Coastguard Worker       Stream.Emit(Magic, 32);
198*9880d681SAndroid Build Coastguard Worker       Stream.EnterSubblock(BlockID, 3);
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker       BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
201*9880d681SAndroid Build Coastguard Worker       Abbrev->Add(BitCodeAbbrevOp(RecordID));
202*9880d681SAndroid Build Coastguard Worker       Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
203*9880d681SAndroid Build Coastguard Worker       AbbrevID = Stream.EmitAbbrev(Abbrev);
204*9880d681SAndroid Build Coastguard Worker       unsigned Record[] = {RecordID};
205*9880d681SAndroid Build Coastguard Worker       Stream.EmitRecordWithBlob(AbbrevID, makeArrayRef(Record), BlobIn);
206*9880d681SAndroid Build Coastguard Worker 
207*9880d681SAndroid Build Coastguard Worker       Stream.ExitBlock();
208*9880d681SAndroid Build Coastguard Worker     }
209*9880d681SAndroid Build Coastguard Worker 
210*9880d681SAndroid Build Coastguard Worker     // Stream the buffer into the reader.
211*9880d681SAndroid Build Coastguard Worker     BitstreamReader R(llvm::make_unique<StreamingMemoryObject>(
212*9880d681SAndroid Build Coastguard Worker         llvm::make_unique<BufferStreamer>(
213*9880d681SAndroid Build Coastguard Worker             StringRef(Buffer.begin(), Buffer.size()))));
214*9880d681SAndroid Build Coastguard Worker     BitstreamCursor Stream(R);
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker     // Header.  Included in test so that we can run llvm-bcanalyzer to debug
217*9880d681SAndroid Build Coastguard Worker     // when there are problems.
218*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(Magic, Stream.Read(32));
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker     // Block.
221*9880d681SAndroid Build Coastguard Worker     BitstreamEntry Entry =
222*9880d681SAndroid Build Coastguard Worker         Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
223*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
224*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(BlockID, Entry.ID);
225*9880d681SAndroid Build Coastguard Worker     ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
226*9880d681SAndroid Build Coastguard Worker 
227*9880d681SAndroid Build Coastguard Worker     // Abbreviation.
228*9880d681SAndroid Build Coastguard Worker     Entry = Stream.advance();
229*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
230*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(AbbrevID, Entry.ID);
231*9880d681SAndroid Build Coastguard Worker 
232*9880d681SAndroid Build Coastguard Worker     // Record.
233*9880d681SAndroid Build Coastguard Worker     StringRef BlobOut;
234*9880d681SAndroid Build Coastguard Worker     SmallVector<uint64_t, 1> Record;
235*9880d681SAndroid Build Coastguard Worker     ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
236*9880d681SAndroid Build Coastguard Worker     EXPECT_TRUE(Record.empty());
237*9880d681SAndroid Build Coastguard Worker     EXPECT_EQ(BlobIn, BlobOut);
238*9880d681SAndroid Build Coastguard Worker   }
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
242