Home | History | Annotate | Download | only in Bitcode
      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 
     16 using namespace llvm;
     17 
     18 namespace {
     19 
     20 class BufferStreamer : public DataStreamer {
     21   StringRef Buffer;
     22 
     23 public:
     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 
     35 TEST(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 
     55 TEST(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 
     66 TEST(BitstreamReaderTest, AtEndOfStreamEmpty) {
     67   uint8_t Dummy = 0xFF;
     68   BitstreamReader Reader(&Dummy, &Dummy);
     69   BitstreamCursor Cursor(Reader);
     70 
     71   EXPECT_TRUE(Cursor.AtEndOfStream());
     72 }
     73 
     74 TEST(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 
     86 TEST(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 
     96 TEST(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 
    106 TEST(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 
    117 TEST(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 
    131 TEST(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 
    145 TEST(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 
    162 TEST(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 
    179 TEST(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