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