1e0308279SFrancis Visoiu Mistrih //===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
2e0308279SFrancis Visoiu Mistrih //
3e0308279SFrancis Visoiu Mistrih // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e0308279SFrancis Visoiu Mistrih // See https://llvm.org/LICENSE.txt for license information.
5e0308279SFrancis Visoiu Mistrih // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e0308279SFrancis Visoiu Mistrih //
7e0308279SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===//
8e0308279SFrancis Visoiu Mistrih
9e0308279SFrancis Visoiu Mistrih #include "llvm/Bitstream/BitstreamReader.h"
10e0308279SFrancis Visoiu Mistrih #include "llvm/ADT/STLExtras.h"
11e0308279SFrancis Visoiu Mistrih #include "llvm/Bitstream/BitstreamWriter.h"
12e0308279SFrancis Visoiu Mistrih #include "gtest/gtest.h"
13e0308279SFrancis Visoiu Mistrih
14e0308279SFrancis Visoiu Mistrih using namespace llvm;
15e0308279SFrancis Visoiu Mistrih
16e0308279SFrancis Visoiu Mistrih namespace {
17e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,AtEndOfStream)18e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, AtEndOfStream) {
19e0308279SFrancis Visoiu Mistrih uint8_t Bytes[4] = {
20e0308279SFrancis Visoiu Mistrih 0x00, 0x01, 0x02, 0x03
21e0308279SFrancis Visoiu Mistrih };
22e0308279SFrancis Visoiu Mistrih BitstreamCursor Cursor(Bytes);
23e0308279SFrancis Visoiu Mistrih
24e0308279SFrancis Visoiu Mistrih EXPECT_FALSE(Cursor.AtEndOfStream());
25e0308279SFrancis Visoiu Mistrih Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(8);
26e0308279SFrancis Visoiu Mistrih EXPECT_TRUE((bool)MaybeRead);
27e0308279SFrancis Visoiu Mistrih EXPECT_FALSE(Cursor.AtEndOfStream());
28e0308279SFrancis Visoiu Mistrih MaybeRead = Cursor.Read(24);
29e0308279SFrancis Visoiu Mistrih EXPECT_TRUE((bool)MaybeRead);
30e0308279SFrancis Visoiu Mistrih EXPECT_TRUE(Cursor.AtEndOfStream());
31e0308279SFrancis Visoiu Mistrih
32e0308279SFrancis Visoiu Mistrih EXPECT_FALSE(Cursor.JumpToBit(0));
33e0308279SFrancis Visoiu Mistrih EXPECT_FALSE(Cursor.AtEndOfStream());
34e0308279SFrancis Visoiu Mistrih
35e0308279SFrancis Visoiu Mistrih EXPECT_FALSE(Cursor.JumpToBit(32));
36e0308279SFrancis Visoiu Mistrih EXPECT_TRUE(Cursor.AtEndOfStream());
37e0308279SFrancis Visoiu Mistrih }
38e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,AtEndOfStreamJump)39e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, AtEndOfStreamJump) {
40e0308279SFrancis Visoiu Mistrih uint8_t Bytes[4] = {
41e0308279SFrancis Visoiu Mistrih 0x00, 0x01, 0x02, 0x03
42e0308279SFrancis Visoiu Mistrih };
43e0308279SFrancis Visoiu Mistrih BitstreamCursor Cursor(Bytes);
44e0308279SFrancis Visoiu Mistrih
45e0308279SFrancis Visoiu Mistrih EXPECT_FALSE(Cursor.JumpToBit(32));
46e0308279SFrancis Visoiu Mistrih EXPECT_TRUE(Cursor.AtEndOfStream());
47e0308279SFrancis Visoiu Mistrih }
48e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,AtEndOfStreamEmpty)49e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
50e0308279SFrancis Visoiu Mistrih BitstreamCursor Cursor(ArrayRef<uint8_t>{});
51e0308279SFrancis Visoiu Mistrih
52e0308279SFrancis Visoiu Mistrih EXPECT_TRUE(Cursor.AtEndOfStream());
53e0308279SFrancis Visoiu Mistrih }
54e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,getCurrentByteNo)55e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, getCurrentByteNo) {
56e0308279SFrancis Visoiu Mistrih uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03};
57e0308279SFrancis Visoiu Mistrih SimpleBitstreamCursor Cursor(Bytes);
58e0308279SFrancis Visoiu Mistrih
59e0308279SFrancis Visoiu Mistrih for (unsigned I = 0, E = 32; I != E; ++I) {
60e0308279SFrancis Visoiu Mistrih EXPECT_EQ(I / 8, Cursor.getCurrentByteNo());
61e0308279SFrancis Visoiu Mistrih Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(1);
62e0308279SFrancis Visoiu Mistrih EXPECT_TRUE((bool)MaybeRead);
63e0308279SFrancis Visoiu Mistrih }
64e0308279SFrancis Visoiu Mistrih EXPECT_EQ(4u, Cursor.getCurrentByteNo());
65e0308279SFrancis Visoiu Mistrih }
66e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,getPointerToByte)67e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, getPointerToByte) {
68e0308279SFrancis Visoiu Mistrih uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
69e0308279SFrancis Visoiu Mistrih SimpleBitstreamCursor Cursor(Bytes);
70e0308279SFrancis Visoiu Mistrih
71e0308279SFrancis Visoiu Mistrih for (unsigned I = 0, E = 8; I != E; ++I) {
72e0308279SFrancis Visoiu Mistrih EXPECT_EQ(Bytes + I, Cursor.getPointerToByte(I, 1));
73e0308279SFrancis Visoiu Mistrih }
74e0308279SFrancis Visoiu Mistrih }
75e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,getPointerToBit)76e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, getPointerToBit) {
77e0308279SFrancis Visoiu Mistrih uint8_t Bytes[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
78e0308279SFrancis Visoiu Mistrih SimpleBitstreamCursor Cursor(Bytes);
79e0308279SFrancis Visoiu Mistrih
80e0308279SFrancis Visoiu Mistrih for (unsigned I = 0, E = 8; I != E; ++I) {
81e0308279SFrancis Visoiu Mistrih EXPECT_EQ(Bytes + I, Cursor.getPointerToBit(I * 8, 1));
82e0308279SFrancis Visoiu Mistrih }
83e0308279SFrancis Visoiu Mistrih }
84e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,readRecordWithBlobWhileStreaming)85e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
86e0308279SFrancis Visoiu Mistrih SmallVector<uint8_t, 1> BlobData;
87e0308279SFrancis Visoiu Mistrih for (unsigned I = 0, E = 1024; I != E; ++I)
88e0308279SFrancis Visoiu Mistrih BlobData.push_back(I);
89e0308279SFrancis Visoiu Mistrih
90e0308279SFrancis Visoiu Mistrih // Try a bunch of different sizes.
91e0308279SFrancis Visoiu Mistrih const unsigned Magic = 0x12345678;
92e0308279SFrancis Visoiu Mistrih const unsigned BlockID = bitc::FIRST_APPLICATION_BLOCKID;
93e0308279SFrancis Visoiu Mistrih const unsigned RecordID = 1;
94e0308279SFrancis Visoiu Mistrih for (unsigned I = 0, BlobSize = 0, E = BlobData.size(); BlobSize < E;
95e0308279SFrancis Visoiu Mistrih BlobSize += ++I) {
96e0308279SFrancis Visoiu Mistrih StringRef BlobIn((const char *)BlobData.begin(), BlobSize);
97e0308279SFrancis Visoiu Mistrih
98e0308279SFrancis Visoiu Mistrih // Write the bitcode.
99e0308279SFrancis Visoiu Mistrih SmallVector<char, 1> Buffer;
100e0308279SFrancis Visoiu Mistrih unsigned AbbrevID;
101e0308279SFrancis Visoiu Mistrih {
102e0308279SFrancis Visoiu Mistrih BitstreamWriter Stream(Buffer);
103e0308279SFrancis Visoiu Mistrih Stream.Emit(Magic, 32);
104e0308279SFrancis Visoiu Mistrih Stream.EnterSubblock(BlockID, 3);
105e0308279SFrancis Visoiu Mistrih
106e0308279SFrancis Visoiu Mistrih auto Abbrev = std::make_shared<BitCodeAbbrev>();
107e0308279SFrancis Visoiu Mistrih Abbrev->Add(BitCodeAbbrevOp(RecordID));
108e0308279SFrancis Visoiu Mistrih Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
109e0308279SFrancis Visoiu Mistrih AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
110e0308279SFrancis Visoiu Mistrih unsigned Record[] = {RecordID};
111*38818b60Sserge-sans-paille Stream.EmitRecordWithBlob(AbbrevID, ArrayRef(Record), BlobIn);
112e0308279SFrancis Visoiu Mistrih
113e0308279SFrancis Visoiu Mistrih Stream.ExitBlock();
114e0308279SFrancis Visoiu Mistrih }
115e0308279SFrancis Visoiu Mistrih
116e0308279SFrancis Visoiu Mistrih // Stream the buffer into the reader.
117e0308279SFrancis Visoiu Mistrih BitstreamCursor Stream(
118e0308279SFrancis Visoiu Mistrih ArrayRef<uint8_t>((const uint8_t *)Buffer.begin(), Buffer.size()));
119e0308279SFrancis Visoiu Mistrih
120e0308279SFrancis Visoiu Mistrih // Header. Included in test so that we can run llvm-bcanalyzer to debug
121e0308279SFrancis Visoiu Mistrih // when there are problems.
122e0308279SFrancis Visoiu Mistrih Expected<SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(32);
123e0308279SFrancis Visoiu Mistrih ASSERT_TRUE((bool)MaybeRead);
124e0308279SFrancis Visoiu Mistrih ASSERT_EQ(Magic, MaybeRead.get());
125e0308279SFrancis Visoiu Mistrih
126e0308279SFrancis Visoiu Mistrih // Block.
127e0308279SFrancis Visoiu Mistrih Expected<BitstreamEntry> MaybeEntry =
128e0308279SFrancis Visoiu Mistrih Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
129e0308279SFrancis Visoiu Mistrih ASSERT_TRUE((bool)MaybeEntry);
130e0308279SFrancis Visoiu Mistrih BitstreamEntry Entry = MaybeEntry.get();
131e0308279SFrancis Visoiu Mistrih ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
132e0308279SFrancis Visoiu Mistrih ASSERT_EQ(BlockID, Entry.ID);
133e0308279SFrancis Visoiu Mistrih ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
134e0308279SFrancis Visoiu Mistrih
135e0308279SFrancis Visoiu Mistrih // Abbreviation.
136e0308279SFrancis Visoiu Mistrih MaybeEntry = Stream.advance();
137e0308279SFrancis Visoiu Mistrih ASSERT_TRUE((bool)MaybeEntry);
138e0308279SFrancis Visoiu Mistrih Entry = MaybeEntry.get();
139e0308279SFrancis Visoiu Mistrih ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
140e0308279SFrancis Visoiu Mistrih ASSERT_EQ(AbbrevID, Entry.ID);
141e0308279SFrancis Visoiu Mistrih
142e0308279SFrancis Visoiu Mistrih // Record.
143e0308279SFrancis Visoiu Mistrih StringRef BlobOut;
144e0308279SFrancis Visoiu Mistrih SmallVector<uint64_t, 1> Record;
145e0308279SFrancis Visoiu Mistrih Expected<unsigned> MaybeRecord =
146e0308279SFrancis Visoiu Mistrih Stream.readRecord(Entry.ID, Record, &BlobOut);
147e0308279SFrancis Visoiu Mistrih ASSERT_TRUE((bool)MaybeRecord);
148e0308279SFrancis Visoiu Mistrih ASSERT_EQ(RecordID, MaybeRecord.get());
149e0308279SFrancis Visoiu Mistrih EXPECT_TRUE(Record.empty());
150e0308279SFrancis Visoiu Mistrih EXPECT_EQ(BlobIn, BlobOut);
151e0308279SFrancis Visoiu Mistrih }
152e0308279SFrancis Visoiu Mistrih }
153e0308279SFrancis Visoiu Mistrih
TEST(BitstreamReaderTest,shortRead)154e0308279SFrancis Visoiu Mistrih TEST(BitstreamReaderTest, shortRead) {
155e0308279SFrancis Visoiu Mistrih uint8_t Bytes[] = {8, 7, 6, 5, 4, 3, 2, 1};
156e0308279SFrancis Visoiu Mistrih for (unsigned I = 1; I != 8; ++I) {
157e0308279SFrancis Visoiu Mistrih SimpleBitstreamCursor Cursor(ArrayRef<uint8_t>(Bytes, I));
158e0308279SFrancis Visoiu Mistrih Expected<SimpleBitstreamCursor::word_t> MaybeRead = Cursor.Read(8);
159e0308279SFrancis Visoiu Mistrih ASSERT_TRUE((bool)MaybeRead);
160e0308279SFrancis Visoiu Mistrih EXPECT_EQ(8ull, MaybeRead.get());
161e0308279SFrancis Visoiu Mistrih }
162e0308279SFrancis Visoiu Mistrih }
163e0308279SFrancis Visoiu Mistrih
1646aa050a6SNathan James static_assert(std::is_trivially_copyable_v<BitCodeAbbrevOp>,
165e0308279SFrancis Visoiu Mistrih "trivially copyable");
166e0308279SFrancis Visoiu Mistrih
167e0308279SFrancis Visoiu Mistrih } // end anonymous namespace
168