1 //===- BitstreamReaderTest.cpp - Tests for BitstreamReader ----------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Bitstream/BitstreamReader.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Bitstream/BitstreamWriter.h"
12 #include "gtest/gtest.h"
18 TEST(BitstreamReaderTest
, AtEndOfStream
) {
20 0x00, 0x01, 0x02, 0x03
22 BitstreamCursor
Cursor(Bytes
);
24 EXPECT_FALSE(Cursor
.AtEndOfStream());
25 Expected
<SimpleBitstreamCursor::word_t
> MaybeRead
= Cursor
.Read(8);
26 EXPECT_TRUE((bool)MaybeRead
);
27 EXPECT_FALSE(Cursor
.AtEndOfStream());
28 MaybeRead
= Cursor
.Read(24);
29 EXPECT_TRUE((bool)MaybeRead
);
30 EXPECT_TRUE(Cursor
.AtEndOfStream());
32 EXPECT_FALSE(Cursor
.JumpToBit(0));
33 EXPECT_FALSE(Cursor
.AtEndOfStream());
35 EXPECT_FALSE(Cursor
.JumpToBit(32));
36 EXPECT_TRUE(Cursor
.AtEndOfStream());
39 TEST(BitstreamReaderTest
, AtEndOfStreamJump
) {
41 0x00, 0x01, 0x02, 0x03
43 BitstreamCursor
Cursor(Bytes
);
45 EXPECT_FALSE(Cursor
.JumpToBit(32));
46 EXPECT_TRUE(Cursor
.AtEndOfStream());
49 TEST(BitstreamReaderTest
, AtEndOfStreamEmpty
) {
50 BitstreamCursor
Cursor(ArrayRef
<uint8_t>{});
52 EXPECT_TRUE(Cursor
.AtEndOfStream());
55 TEST(BitstreamReaderTest
, getCurrentByteNo
) {
56 uint8_t Bytes
[] = {0x00, 0x01, 0x02, 0x03};
57 SimpleBitstreamCursor
Cursor(Bytes
);
59 for (unsigned I
= 0, E
= 32; I
!= E
; ++I
) {
60 EXPECT_EQ(I
/ 8, Cursor
.getCurrentByteNo());
61 Expected
<SimpleBitstreamCursor::word_t
> MaybeRead
= Cursor
.Read(1);
62 EXPECT_TRUE((bool)MaybeRead
);
64 EXPECT_EQ(4u, Cursor
.getCurrentByteNo());
67 TEST(BitstreamReaderTest
, getPointerToByte
) {
68 uint8_t Bytes
[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
69 SimpleBitstreamCursor
Cursor(Bytes
);
71 for (unsigned I
= 0, E
= 8; I
!= E
; ++I
) {
72 EXPECT_EQ(Bytes
+ I
, Cursor
.getPointerToByte(I
, 1));
76 TEST(BitstreamReaderTest
, getPointerToBit
) {
77 uint8_t Bytes
[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
78 SimpleBitstreamCursor
Cursor(Bytes
);
80 for (unsigned I
= 0, E
= 8; I
!= E
; ++I
) {
81 EXPECT_EQ(Bytes
+ I
, Cursor
.getPointerToBit(I
* 8, 1));
85 TEST(BitstreamReaderTest
, readRecordWithBlobWhileStreaming
) {
86 SmallVector
<uint8_t, 1> BlobData
;
87 for (unsigned I
= 0, E
= 1024; I
!= E
; ++I
)
88 BlobData
.push_back(I
);
90 // Try a bunch of different sizes.
91 const unsigned Magic
= 0x12345678;
92 const unsigned BlockID
= bitc::FIRST_APPLICATION_BLOCKID
;
93 const unsigned RecordID
= 1;
94 for (unsigned I
= 0, BlobSize
= 0, E
= BlobData
.size(); BlobSize
< E
;
96 StringRef
BlobIn((const char *)BlobData
.begin(), BlobSize
);
99 SmallVector
<char, 1> Buffer
;
102 BitstreamWriter
Stream(Buffer
);
103 Stream
.Emit(Magic
, 32);
104 Stream
.EnterSubblock(BlockID
, 3);
106 auto Abbrev
= std::make_shared
<BitCodeAbbrev
>();
107 Abbrev
->Add(BitCodeAbbrevOp(RecordID
));
108 Abbrev
->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob
));
109 AbbrevID
= Stream
.EmitAbbrev(std::move(Abbrev
));
110 unsigned Record
[] = {RecordID
};
111 Stream
.EmitRecordWithBlob(AbbrevID
, ArrayRef(Record
), BlobIn
);
116 // Stream the buffer into the reader.
117 BitstreamCursor
Stream(
118 ArrayRef
<uint8_t>((const uint8_t *)Buffer
.begin(), Buffer
.size()));
120 // Header. Included in test so that we can run llvm-bcanalyzer to debug
121 // when there are problems.
122 Expected
<SimpleBitstreamCursor::word_t
> MaybeRead
= Stream
.Read(32);
123 ASSERT_TRUE((bool)MaybeRead
);
124 ASSERT_EQ(Magic
, MaybeRead
.get());
127 Expected
<BitstreamEntry
> MaybeEntry
=
128 Stream
.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs
);
129 ASSERT_TRUE((bool)MaybeEntry
);
130 BitstreamEntry Entry
= MaybeEntry
.get();
131 ASSERT_EQ(BitstreamEntry::SubBlock
, Entry
.Kind
);
132 ASSERT_EQ(BlockID
, Entry
.ID
);
133 ASSERT_FALSE(Stream
.EnterSubBlock(BlockID
));
136 MaybeEntry
= Stream
.advance();
137 ASSERT_TRUE((bool)MaybeEntry
);
138 Entry
= MaybeEntry
.get();
139 ASSERT_EQ(BitstreamEntry::Record
, Entry
.Kind
);
140 ASSERT_EQ(AbbrevID
, Entry
.ID
);
144 SmallVector
<uint64_t, 1> Record
;
145 Expected
<unsigned> MaybeRecord
=
146 Stream
.readRecord(Entry
.ID
, Record
, &BlobOut
);
147 ASSERT_TRUE((bool)MaybeRecord
);
148 ASSERT_EQ(RecordID
, MaybeRecord
.get());
149 EXPECT_TRUE(Record
.empty());
150 EXPECT_EQ(BlobIn
, BlobOut
);
154 TEST(BitstreamReaderTest
, shortRead
) {
155 uint8_t Bytes
[] = {8, 7, 6, 5, 4, 3, 2, 1};
156 for (unsigned I
= 1; I
!= 8; ++I
) {
157 SimpleBitstreamCursor
Cursor(ArrayRef
<uint8_t>(Bytes
, I
));
158 Expected
<SimpleBitstreamCursor::word_t
> MaybeRead
= Cursor
.Read(8);
159 ASSERT_TRUE((bool)MaybeRead
);
160 EXPECT_EQ(8ull, MaybeRead
.get());
164 static_assert(std::is_trivially_copyable_v
<BitCodeAbbrevOp
>,
165 "trivially copyable");
167 } // end anonymous namespace