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/Bitcode/BitstreamReader.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/Bitcode/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());
26 EXPECT_FALSE(Cursor
.AtEndOfStream());
27 (void)Cursor
.Read(24);
28 EXPECT_TRUE(Cursor
.AtEndOfStream());
31 EXPECT_FALSE(Cursor
.AtEndOfStream());
34 EXPECT_TRUE(Cursor
.AtEndOfStream());
37 TEST(BitstreamReaderTest
, AtEndOfStreamJump
) {
39 0x00, 0x01, 0x02, 0x03
41 BitstreamCursor
Cursor(Bytes
);
44 EXPECT_TRUE(Cursor
.AtEndOfStream());
47 TEST(BitstreamReaderTest
, AtEndOfStreamEmpty
) {
48 BitstreamCursor
Cursor(ArrayRef
<uint8_t>{});
50 EXPECT_TRUE(Cursor
.AtEndOfStream());
53 TEST(BitstreamReaderTest
, getCurrentByteNo
) {
54 uint8_t Bytes
[] = {0x00, 0x01, 0x02, 0x03};
55 SimpleBitstreamCursor
Cursor(Bytes
);
57 for (unsigned I
= 0, E
= 32; I
!= E
; ++I
) {
58 EXPECT_EQ(I
/ 8, Cursor
.getCurrentByteNo());
61 EXPECT_EQ(4u, Cursor
.getCurrentByteNo());
64 TEST(BitstreamReaderTest
, getPointerToByte
) {
65 uint8_t Bytes
[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
66 SimpleBitstreamCursor
Cursor(Bytes
);
68 for (unsigned I
= 0, E
= 8; I
!= E
; ++I
) {
69 EXPECT_EQ(Bytes
+ I
, Cursor
.getPointerToByte(I
, 1));
73 TEST(BitstreamReaderTest
, getPointerToBit
) {
74 uint8_t Bytes
[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
75 SimpleBitstreamCursor
Cursor(Bytes
);
77 for (unsigned I
= 0, E
= 8; I
!= E
; ++I
) {
78 EXPECT_EQ(Bytes
+ I
, Cursor
.getPointerToBit(I
* 8, 1));
82 TEST(BitstreamReaderTest
, readRecordWithBlobWhileStreaming
) {
83 SmallVector
<uint8_t, 1> BlobData
;
84 for (unsigned I
= 0, E
= 1024; I
!= E
; ++I
)
85 BlobData
.push_back(I
);
87 // Try a bunch of different sizes.
88 const unsigned Magic
= 0x12345678;
89 const unsigned BlockID
= bitc::FIRST_APPLICATION_BLOCKID
;
90 const unsigned RecordID
= 1;
91 for (unsigned I
= 0, BlobSize
= 0, E
= BlobData
.size(); BlobSize
< E
;
93 StringRef
BlobIn((const char *)BlobData
.begin(), BlobSize
);
96 SmallVector
<char, 1> Buffer
;
99 BitstreamWriter
Stream(Buffer
);
100 Stream
.Emit(Magic
, 32);
101 Stream
.EnterSubblock(BlockID
, 3);
103 auto Abbrev
= std::make_shared
<BitCodeAbbrev
>();
104 Abbrev
->Add(BitCodeAbbrevOp(RecordID
));
105 Abbrev
->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob
));
106 AbbrevID
= Stream
.EmitAbbrev(std::move(Abbrev
));
107 unsigned Record
[] = {RecordID
};
108 Stream
.EmitRecordWithBlob(AbbrevID
, makeArrayRef(Record
), BlobIn
);
113 // Stream the buffer into the reader.
114 BitstreamCursor
Stream(
115 ArrayRef
<uint8_t>((const uint8_t *)Buffer
.begin(), Buffer
.size()));
117 // Header. Included in test so that we can run llvm-bcanalyzer to debug
118 // when there are problems.
119 ASSERT_EQ(Magic
, Stream
.Read(32));
122 BitstreamEntry Entry
=
123 Stream
.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs
);
124 ASSERT_EQ(BitstreamEntry::SubBlock
, Entry
.Kind
);
125 ASSERT_EQ(BlockID
, Entry
.ID
);
126 ASSERT_FALSE(Stream
.EnterSubBlock(BlockID
));
129 Entry
= Stream
.advance();
130 ASSERT_EQ(BitstreamEntry::Record
, Entry
.Kind
);
131 ASSERT_EQ(AbbrevID
, Entry
.ID
);
135 SmallVector
<uint64_t, 1> Record
;
136 ASSERT_EQ(RecordID
, Stream
.readRecord(Entry
.ID
, Record
, &BlobOut
));
137 EXPECT_TRUE(Record
.empty());
138 EXPECT_EQ(BlobIn
, BlobOut
);
142 TEST(BitstreamReaderTest
, shortRead
) {
143 uint8_t Bytes
[] = {8, 7, 6, 5, 4, 3, 2, 1};
144 for (unsigned I
= 1; I
!= 8; ++I
) {
145 SimpleBitstreamCursor
Cursor(ArrayRef
<uint8_t>(Bytes
, I
));
146 EXPECT_EQ(8ull, Cursor
.Read(8));
150 static_assert(is_trivially_copyable
<BitCodeAbbrevOp
>::value
,
151 "trivially copyable");
153 } // end anonymous namespace