1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===//
2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//                     The LLVM Compiler Infrastructure
4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source
6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details.
7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===//
9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This header defines the BitstreamReader class.  This class can be used to
11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// read an arbitrary bitstream, regardless of its contents.
12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===//
14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_BITCODE_BITSTREAMREADER_H
16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_BITCODE_BITSTREAMREADER_H
17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/ArrayRef.h"
19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/SmallVector.h"
20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Bitcode/BitCodes.h"
21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/Endian.h"
22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/ErrorHandling.h"
23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/MathExtras.h"
24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Support/MemoryBuffer.h"
25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <algorithm>
26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cassert>
27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <climits>
28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cstddef>
29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cstdint>
30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <memory>
31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <string>
32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <utility>
33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <vector>
34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm {
36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This class maintains the abbreviations read from a block info block.
38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass BitstreamBlockInfo {
39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This contains information emitted to BLOCKINFO_BLOCK blocks. These
41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// describe abbreviations that all blocks of the specified ID inherit.
42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  struct BlockInfo {
43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned BlockID;
44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs;
45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    std::string Name;
46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    std::vector<std::pair<unsigned, std::string> > RecordNames;
47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  };
48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate:
50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  std::vector<BlockInfo> BlockInfoRecords;
51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// If there is block info for the specified ID, return it, otherwise return
54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// null.
55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const BlockInfo *getBlockInfo(unsigned BlockID) const {
56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Common case, the most recent entry matches BlockID.
57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return &BlockInfoRecords.back();
59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size());
61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot         i != e; ++i)
62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (BlockInfoRecords[i].BlockID == BlockID)
63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return &BlockInfoRecords[i];
64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return nullptr;
65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (const BlockInfo *BI = getBlockInfo(BlockID))
69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return *const_cast<BlockInfo*>(BI);
70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Otherwise, add a new record.
72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BlockInfoRecords.emplace_back();
73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BlockInfoRecords.back().BlockID = BlockID;
74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return BlockInfoRecords.back();
75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This represents a position within a bitstream. There may be multiple
79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// independent cursors reading within one bitstream, each maintaining their
80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// own local state.
81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass SimpleBitstreamCursor {
82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ArrayRef<uint8_t> BitcodeBytes;
83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  size_t NextChar = 0;
84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is the current data we have pulled from the stream but have not
87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// returned to the client. This is specifically and intentionally defined to
88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// follow the word size of the host machine for efficiency. We use word_t in
89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// places that are aware of this to make it perfectly explicit what is going
90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// on.
91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  typedef size_t word_t;
92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate:
94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  word_t CurWord = 0;
95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is the number of bits in CurWord that are valid. This is always from
97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// [0...bits_of(size_t)-1] inclusive.
98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned BitsInCurWord = 0;
99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static const size_t MaxChunkSize = sizeof(word_t) * 8;
102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  SimpleBitstreamCursor() = default;
104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit SimpleBitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)
105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      : BitcodeBytes(BitcodeBytes) {}
106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit SimpleBitstreamCursor(StringRef BitcodeBytes)
107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      : BitcodeBytes(reinterpret_cast<const uint8_t *>(BitcodeBytes.data()),
108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                     BitcodeBytes.size()) {}
109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit SimpleBitstreamCursor(MemoryBufferRef BitcodeBytes)
110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      : SimpleBitstreamCursor(BitcodeBytes.getBuffer()) {}
111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool canSkipToPos(size_t pos) const {
113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // pos can be skipped to if it is a valid address or one byte past the end.
114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return pos <= BitcodeBytes.size();
115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool AtEndOfStream() {
118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return BitsInCurWord == 0 && BitcodeBytes.size() <= NextChar;
119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Return the bit # of the bit we are reading.
122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t GetCurrentBitNo() const {
123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return NextChar*CHAR_BIT - BitsInCurWord;
124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // Return the byte # of the current bit.
127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t getCurrentByteNo() const { return GetCurrentBitNo() / 8; }
128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ArrayRef<uint8_t> getBitcodeBytes() const { return BitcodeBytes; }
130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Reset the stream to the specified bit number.
132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void JumpToBit(uint64_t BitNo) {
133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    size_t ByteNo = size_t(BitNo/8) & ~(sizeof(word_t)-1);
134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    assert(canSkipToPos(ByteNo) && "Invalid location");
136c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
137c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Move the cursor to the right word.
138c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    NextChar = ByteNo;
139c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitsInCurWord = 0;
140c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
141c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Skip over any bits that are already consumed.
142c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (WordBitNo)
143c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Read(WordBitNo);
144c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
145c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
146c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Get a pointer into the bitstream at the specified byte offset.
147c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) {
148c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return BitcodeBytes.data() + ByteNo;
149c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
150c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
151c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Get a pointer into the bitstream at the specified bit offset.
152c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
153c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// The bit offset must be on a byte boundary.
154c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const uint8_t *getPointerToBit(uint64_t BitNo, uint64_t NumBytes) {
155c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    assert(!(BitNo % 8) && "Expected bit on byte boundary");
156c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return getPointerToByte(BitNo / 8, NumBytes);
157c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
158c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
159c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void fillCurWord() {
160c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (NextChar >= BitcodeBytes.size())
161c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      report_fatal_error("Unexpected end of file");
162c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
163c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Read the next word from the stream.
164c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    const uint8_t *NextCharPtr = BitcodeBytes.data() + NextChar;
165c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned BytesRead;
166c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (BitcodeBytes.size() >= NextChar + sizeof(word_t)) {
167c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      BytesRead = sizeof(word_t);
168c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      CurWord =
169c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot          support::endian::read<word_t, support::little, support::unaligned>(
170c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot              NextCharPtr);
171c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    } else {
172c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      // Short read.
173c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      BytesRead = BitcodeBytes.size() - NextChar;
174c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      CurWord = 0;
175c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      for (unsigned B = 0; B != BytesRead; ++B)
176c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        CurWord |= uint64_t(NextCharPtr[B]) << (B * 8);
177c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
178c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    NextChar += BytesRead;
179c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitsInCurWord = BytesRead * 8;
180c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
181c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
182c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  word_t Read(unsigned NumBits) {
183c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    static const unsigned BitsInWord = MaxChunkSize;
184c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
185c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    assert(NumBits && NumBits <= BitsInWord &&
186c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot           "Cannot return zero or more than BitsInWord bits!");
187c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
188c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f;
189c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
190c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // If the field is fully contained by CurWord, return it quickly.
191c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (BitsInCurWord >= NumBits) {
192c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      word_t R = CurWord & (~word_t(0) >> (BitsInWord - NumBits));
193c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
194c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      // Use a mask to avoid undefined behavior.
195c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      CurWord >>= (NumBits & Mask);
196c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
197c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      BitsInCurWord -= NumBits;
198c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return R;
199c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
200c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
201c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    word_t R = BitsInCurWord ? CurWord : 0;
202c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned BitsLeft = NumBits - BitsInCurWord;
203c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
204c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    fillCurWord();
205c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
206c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // If we run out of data, abort.
207c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (BitsLeft > BitsInCurWord)
208c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      report_fatal_error("Unexpected end of file");
209c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
210c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft));
211c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
212c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Use a mask to avoid undefined behavior.
213c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    CurWord >>= (BitsLeft & Mask);
214c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
215c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitsInCurWord -= BitsLeft;
216c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
217c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    R |= R2 << (NumBits - BitsLeft);
218c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
219c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return R;
220c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
221c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
222c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint32_t ReadVBR(unsigned NumBits) {
223c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    uint32_t Piece = Read(NumBits);
224c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if ((Piece & (1U << (NumBits-1))) == 0)
225c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return Piece;
226c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
227c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    uint32_t Result = 0;
228c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned NextBit = 0;
229c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    while (true) {
230c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
231c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
232c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if ((Piece & (1U << (NumBits-1))) == 0)
233c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return Result;
234c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
235c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      NextBit += NumBits-1;
236c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Piece = Read(NumBits);
237c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
238c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
239c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
240c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // Read a VBR that may have a value up to 64-bits in size. The chunk size of
241c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // the VBR must still be <= 32 bits though.
242c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  uint64_t ReadVBR64(unsigned NumBits) {
243c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    uint32_t Piece = Read(NumBits);
244c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if ((Piece & (1U << (NumBits-1))) == 0)
245c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return uint64_t(Piece);
246c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
247c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    uint64_t Result = 0;
248c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned NextBit = 0;
249c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    while (true) {
250c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit;
251c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
252c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if ((Piece & (1U << (NumBits-1))) == 0)
253c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return Result;
254c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
255c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      NextBit += NumBits-1;
256c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Piece = Read(NumBits);
257c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
258c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
259c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
260c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void SkipToFourByteBoundary() {
261c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // If word_t is 64-bits and if we've read less than 32 bits, just dump
262c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // the bits we have up to the next 32-bit boundary.
263c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (sizeof(word_t) > 4 &&
264c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        BitsInCurWord >= 32) {
265c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      CurWord >>= BitsInCurWord-32;
266c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      BitsInCurWord = 32;
267c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return;
268c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
269c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
270c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitsInCurWord = 0;
271c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
272c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
273c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Skip to the end of the file.
274c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void skipToEnd() { NextChar = BitcodeBytes.size(); }
275c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
276c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
277c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// When advancing through a bitstream cursor, each advance can discover a few
278c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// different kinds of entries:
279c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotstruct BitstreamEntry {
280c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  enum {
281c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Error,    // Malformed bitcode was found.
282c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    EndBlock, // We've reached the end of the current block, (or the end of the
283c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot              // file, which is treated like a series of EndBlock records.
284c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    SubBlock, // This is the start of a new subblock of a specific ID.
285c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Record    // This is a record with a specific AbbrevID.
286c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  } Kind;
287c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
288c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned ID;
289c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
290c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static BitstreamEntry getError() {
291c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitstreamEntry E; E.Kind = Error; return E;
292c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
293c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
294c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static BitstreamEntry getEndBlock() {
295c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitstreamEntry E; E.Kind = EndBlock; return E;
296c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
297c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
298c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static BitstreamEntry getSubBlock(unsigned ID) {
299c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E;
300c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
301c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
302c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static BitstreamEntry getRecord(unsigned AbbrevID) {
303c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E;
304c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
305c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
306c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
307c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// This represents a position within a bitcode file, implemented on top of a
308c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// SimpleBitstreamCursor.
309c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot///
310c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not
311c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// be passed by value.
312c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass BitstreamCursor : SimpleBitstreamCursor {
313c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // This is the declared size of code values used for the current block, in
314c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // bits.
315c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned CurCodeSize = 2;
316c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
317c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Abbrevs installed at in this block.
318c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs;
319c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
320c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  struct Block {
321c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned PrevCodeSize;
322c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs;
323c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
324c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    explicit Block(unsigned PCS) : PrevCodeSize(PCS) {}
325c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  };
326c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
327c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This tracks the codesize of parent blocks.
328c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  SmallVector<Block, 8> BlockScope;
329c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
330c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  BitstreamBlockInfo *BlockInfo = nullptr;
331c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
332c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
333c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  static const size_t MaxChunkSize = sizeof(word_t) * 8;
334c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
335c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  BitstreamCursor() = default;
336c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit BitstreamCursor(ArrayRef<uint8_t> BitcodeBytes)
337c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      : SimpleBitstreamCursor(BitcodeBytes) {}
338c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit BitstreamCursor(StringRef BitcodeBytes)
339c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      : SimpleBitstreamCursor(BitcodeBytes) {}
340c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  explicit BitstreamCursor(MemoryBufferRef BitcodeBytes)
341c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      : SimpleBitstreamCursor(BitcodeBytes) {}
342c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
343c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::canSkipToPos;
344c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::AtEndOfStream;
345c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::getBitcodeBytes;
346c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::GetCurrentBitNo;
347c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::getCurrentByteNo;
348c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::getPointerToByte;
349c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::JumpToBit;
350c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::fillCurWord;
351c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::Read;
352c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::ReadVBR;
353c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  using SimpleBitstreamCursor::ReadVBR64;
354c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
355c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Return the number of bits used to encode an abbrev #.
356c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned getAbbrevIDWidth() const { return CurCodeSize; }
357c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
358c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Flags that modify the behavior of advance().
359c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  enum {
360c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    /// If this flag is used, the advance() method does not automatically pop
361c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    /// the block scope when the end of a block is reached.
362c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    AF_DontPopBlockAtEnd = 1,
363c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
364c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    /// If this flag is used, abbrev entries are returned just like normal
365c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    /// records.
366c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    AF_DontAutoprocessAbbrevs = 2
367c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  };
368c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
369c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Advance the current bitstream, returning the next entry in the stream.
370c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  BitstreamEntry advance(unsigned Flags = 0) {
371c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    while (true) {
372c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (AtEndOfStream())
373c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return BitstreamEntry::getError();
374c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
375c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      unsigned Code = ReadCode();
376c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (Code == bitc::END_BLOCK) {
377c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        // Pop the end of the block unless Flags tells us not to.
378c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd())
379c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot          return BitstreamEntry::getError();
380c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return BitstreamEntry::getEndBlock();
381c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      }
382c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
383c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (Code == bitc::ENTER_SUBBLOCK)
384c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return BitstreamEntry::getSubBlock(ReadSubBlockID());
385c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
386c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (Code == bitc::DEFINE_ABBREV &&
387c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot          !(Flags & AF_DontAutoprocessAbbrevs)) {
388c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        // We read and accumulate abbrev's, the client can't do anything with
389c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        // them anyway.
390c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        ReadAbbrevRecord();
391c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        continue;
392c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      }
393c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
394c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return BitstreamEntry::getRecord(Code);
395c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
396c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
397c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
398c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is a convenience function for clients that don't expect any
399c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// subblocks. This just skips over them automatically.
400c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) {
401c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    while (true) {
402c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      // If we found a normal entry, return it.
403c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      BitstreamEntry Entry = advance(Flags);
404c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (Entry.Kind != BitstreamEntry::SubBlock)
405c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return Entry;
406c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
407c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      // If we found a sub-block, just skip over it and check the next entry.
408c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (SkipBlock())
409c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return BitstreamEntry::getError();
410c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
411c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
412c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
413c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned ReadCode() {
414c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return Read(CurCodeSize);
415c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
416c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
417c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // Block header:
418c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  //    [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
419c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
420c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block.
421c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned ReadSubBlockID() {
422c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return ReadVBR(bitc::BlockIDWidth);
423c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
424c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
425c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body
426c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// of this block. If the block record is malformed, return true.
427c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool SkipBlock() {
428c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Read and ignore the codelen value.  Since we are skipping this block, we
429c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // don't care what code widths are used inside of it.
430c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    ReadVBR(bitc::CodeLenWidth);
431c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    SkipToFourByteBoundary();
432c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned NumFourBytes = Read(bitc::BlockSizeWidth);
433c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
434c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Check that the block wasn't partially defined, and that the offset isn't
435c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // bogus.
436c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8;
437c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (AtEndOfStream() || !canSkipToPos(SkipTo/8))
438c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      return true;
439c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
440c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    JumpToBit(SkipTo);
441c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return false;
442c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
443c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
444c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true
445c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// if the block has an error.
446c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr);
447c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
448c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool ReadBlockEnd() {
449c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (BlockScope.empty()) return true;
450c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
451c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    // Block tail:
452c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    //    [END_BLOCK, <align4bytes>]
453c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    SkipToFourByteBoundary();
454c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
455c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    popBlockScope();
456c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return false;
457c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
458c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
459c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate:
460c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void popBlockScope() {
461c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    CurCodeSize = BlockScope.back().PrevCodeSize;
462c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
463c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    CurAbbrevs = std::move(BlockScope.back().PrevAbbrevs);
464c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    BlockScope.pop_back();
465c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
466c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
467c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  //===--------------------------------------------------------------------===//
468c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // Record Processing
469c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  //===--------------------------------------------------------------------===//
470c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
471c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
472c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Return the abbreviation for the specified AbbrevId.
473c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) {
474c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    unsigned AbbrevNo = AbbrevID - bitc::FIRST_APPLICATION_ABBREV;
475c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    if (AbbrevNo >= CurAbbrevs.size())
476c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      report_fatal_error("Invalid abbrev number");
477c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return CurAbbrevs[AbbrevNo].get();
478c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
479c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
480c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Read the current record and discard it, returning the code for the record.
481c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned skipRecord(unsigned AbbrevID);
482c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
483c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
484c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot                      StringRef *Blob = nullptr);
485c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
486c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  //===--------------------------------------------------------------------===//
487c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  // Abbrev Processing
488c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  //===--------------------------------------------------------------------===//
489c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void ReadAbbrevRecord();
490c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
491c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Read and return a block info block from the bitstream. If an error was
492c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// encountered, return None.
493c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ///
494c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \param ReadBlockInfoNames Whether to read block/record name information in
495c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// the BlockInfo block. Only llvm-bcanalyzer uses this.
496c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  Optional<BitstreamBlockInfo>
497c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  ReadBlockInfoBlock(bool ReadBlockInfoNames = false);
498c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
499c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Set the block info to be used by this BitstreamCursor to interpret
500c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// abbreviated records.
501c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void setBlockInfo(BitstreamBlockInfo *BI) { BlockInfo = BI; }
502c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
503c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
504c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end llvm namespace
505c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
506c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_BITCODE_BITSTREAMREADER_H
507