|
@@ -7,13 +7,31 @@
|
|
|
//
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
+#include "llvm/ADT/STLExtras.h"
|
|
|
#include "llvm/Bitcode/BitstreamReader.h"
|
|
|
+#include "llvm/Bitcode/BitstreamWriter.h"
|
|
|
+#include "llvm/Support/StreamingMemoryObject.h"
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
+class BufferStreamer : public DataStreamer {
|
|
|
+ StringRef Buffer;
|
|
|
+
|
|
|
+public:
|
|
|
+ BufferStreamer(StringRef Buffer) : Buffer(Buffer) {}
|
|
|
+ size_t GetBytes(unsigned char *OutBuffer, size_t Length) override {
|
|
|
+ if (Length >= Buffer.size())
|
|
|
+ Length = Buffer.size();
|
|
|
+
|
|
|
+ std::copy(Buffer.begin(), Buffer.begin() + Length, OutBuffer);
|
|
|
+ Buffer = Buffer.drop_front(Length);
|
|
|
+ return Length;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
TEST(BitstreamReaderTest, AtEndOfStream) {
|
|
|
uint8_t Bytes[4] = {
|
|
|
0x00, 0x01, 0x02, 0x03
|
|
@@ -165,4 +183,65 @@ TEST(BitstreamReaderTest, setArtificialByteLimitPastTheEndKnown) {
|
|
|
EXPECT_TRUE(Cursor.AtEndOfStream());
|
|
|
}
|
|
|
|
|
|
+TEST(BitstreamReaderTest, readRecordWithBlobWhileStreaming) {
|
|
|
+ SmallVector<uint8_t, 1> BlobData;
|
|
|
+ for (unsigned I = 0, E = 1024; I != E; ++I)
|
|
|
+ BlobData.push_back(I);
|
|
|
+
|
|
|
+ // Try a bunch of different sizes.
|
|
|
+ const unsigned Magic = 0x12345678;
|
|
|
+ const unsigned BlockID = bitc::FIRST_APPLICATION_BLOCKID;
|
|
|
+ const unsigned RecordID = 1;
|
|
|
+ for (unsigned I = 0, BlobSize = 0, E = BlobData.size(); BlobSize < E;
|
|
|
+ BlobSize += ++I) {
|
|
|
+ StringRef BlobIn((const char *)BlobData.begin(), BlobSize);
|
|
|
+
|
|
|
+ // Write the bitcode.
|
|
|
+ SmallVector<char, 1> Buffer;
|
|
|
+ unsigned AbbrevID;
|
|
|
+ {
|
|
|
+ BitstreamWriter Stream(Buffer);
|
|
|
+ Stream.Emit(Magic, 32);
|
|
|
+ Stream.EnterSubblock(BlockID, 3);
|
|
|
+
|
|
|
+ BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
|
|
|
+ Abbrev->Add(BitCodeAbbrevOp(RecordID));
|
|
|
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
|
|
+ AbbrevID = Stream.EmitAbbrev(Abbrev);
|
|
|
+ unsigned Record[] = {RecordID};
|
|
|
+ Stream.EmitRecordWithBlob(AbbrevID, makeArrayRef(Record), BlobIn);
|
|
|
+
|
|
|
+ Stream.ExitBlock();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Stream the buffer into the reader.
|
|
|
+ BitstreamReader R(make_unique<StreamingMemoryObject>(
|
|
|
+ make_unique<BufferStreamer>(StringRef(Buffer.begin(), Buffer.size()))));
|
|
|
+ BitstreamCursor Stream(R);
|
|
|
+
|
|
|
+ // Header. Included in test so that we can run llvm-bcanalyzer to debug
|
|
|
+ // when there are problems.
|
|
|
+ ASSERT_EQ(Magic, Stream.Read(32));
|
|
|
+
|
|
|
+ // Block.
|
|
|
+ BitstreamEntry Entry =
|
|
|
+ Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs);
|
|
|
+ ASSERT_EQ(BitstreamEntry::SubBlock, Entry.Kind);
|
|
|
+ ASSERT_EQ(BlockID, Entry.ID);
|
|
|
+ ASSERT_FALSE(Stream.EnterSubBlock(BlockID));
|
|
|
+
|
|
|
+ // Abbreviation.
|
|
|
+ Entry = Stream.advance();
|
|
|
+ ASSERT_EQ(BitstreamEntry::Record, Entry.Kind);
|
|
|
+ ASSERT_EQ(AbbrevID, Entry.ID);
|
|
|
+
|
|
|
+ // Record.
|
|
|
+ StringRef BlobOut;
|
|
|
+ SmallVector<uint64_t, 1> Record;
|
|
|
+ ASSERT_EQ(RecordID, Stream.readRecord(Entry.ID, Record, &BlobOut));
|
|
|
+ EXPECT_TRUE(Record.empty());
|
|
|
+ EXPECT_EQ(BlobIn, BlobOut);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
} // end anonymous namespace
|