LLVM  3.7.0
BitstreamReader.cpp
Go to the documentation of this file.
1 //===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
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 
11 
12 using namespace llvm;
13 
14 //===----------------------------------------------------------------------===//
15 // BitstreamCursor implementation
16 //===----------------------------------------------------------------------===//
17 
19  // Free all the Abbrevs.
20  CurAbbrevs.clear();
21 
22  // Free all the Abbrevs in the block scope.
23  BlockScope.clear();
24 }
25 
26 /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
27 /// the block, and return true if the block has an error.
28 bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
29  // Save the current block's state on BlockScope.
30  BlockScope.push_back(Block(CurCodeSize));
31  BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
32 
33  // Add the abbrevs specific to this block to the CurAbbrevs list.
34  if (const BitstreamReader::BlockInfo *Info =
35  BitStream->getBlockInfo(BlockID)) {
36  CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
37  Info->Abbrevs.end());
38  }
39 
40  // Get the codesize of this block.
41  CurCodeSize = ReadVBR(bitc::CodeLenWidth);
42  // We can't read more than MaxChunkSize at a time
43  if (CurCodeSize > MaxChunkSize)
44  return true;
45 
46  SkipToFourByteBoundary();
47  unsigned NumWords = Read(bitc::BlockSizeWidth);
48  if (NumWordsP) *NumWordsP = NumWords;
49 
50  // Validate that this block is sane.
51  return CurCodeSize == 0 || AtEndOfStream();
52 }
53 
54 static uint64_t readAbbreviatedField(BitstreamCursor &Cursor,
55  const BitCodeAbbrevOp &Op) {
56  assert(!Op.isLiteral() && "Not to be used with literals!");
57 
58  // Decode the value as we are commanded.
59  switch (Op.getEncoding()) {
62  llvm_unreachable("Should not reach here");
64  assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
65  return Cursor.Read((unsigned)Op.getEncodingData());
67  assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
68  return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
70  return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6));
71  }
72  llvm_unreachable("invalid abbreviation encoding");
73 }
74 
76  const BitCodeAbbrevOp &Op) {
77  assert(!Op.isLiteral() && "Not to be used with literals!");
78 
79  // Decode the value as we are commanded.
80  switch (Op.getEncoding()) {
83  llvm_unreachable("Should not reach here");
85  assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
86  Cursor.Read((unsigned)Op.getEncodingData());
87  break;
89  assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
90  Cursor.ReadVBR64((unsigned)Op.getEncodingData());
91  break;
93  Cursor.Read(6);
94  break;
95  }
96 }
97 
98 
99 
100 /// skipRecord - Read the current record and discard it.
101 void BitstreamCursor::skipRecord(unsigned AbbrevID) {
102  // Skip unabbreviated records by reading past their entries.
103  if (AbbrevID == bitc::UNABBREV_RECORD) {
104  unsigned Code = ReadVBR(6);
105  (void)Code;
106  unsigned NumElts = ReadVBR(6);
107  for (unsigned i = 0; i != NumElts; ++i)
108  (void)ReadVBR64(6);
109  return;
110  }
111 
112  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
113 
114  for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
115  const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
116  if (Op.isLiteral())
117  continue;
118 
119  if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
121  skipAbbreviatedField(*this, Op);
122  continue;
123  }
124 
125  if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
126  // Array case. Read the number of elements as a vbr6.
127  unsigned NumElts = ReadVBR(6);
128 
129  // Get the element encoding.
130  assert(i+2 == e && "array op not second to last?");
131  const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
132 
133  // Read all the elements.
134  for (; NumElts; --NumElts)
135  skipAbbreviatedField(*this, EltEnc);
136  continue;
137  }
138 
139  assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
140  // Blob case. Read the number of bytes as a vbr6.
141  unsigned NumElts = ReadVBR(6);
142  SkipToFourByteBoundary(); // 32-bit alignment
143 
144  // Figure out where the end of this blob will be including tail padding.
145  size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8;
146 
147  // If this would read off the end of the bitcode file, just set the
148  // record to empty and return.
149  if (!canSkipToPos(NewEnd/8)) {
150  NextChar = BitStream->getBitcodeBytes().getExtent();
151  break;
152  }
153 
154  // Skip over the blob.
155  JumpToBit(NewEnd);
156  }
157 }
158 
159 unsigned BitstreamCursor::readRecord(unsigned AbbrevID,
161  StringRef *Blob) {
162  if (AbbrevID == bitc::UNABBREV_RECORD) {
163  unsigned Code = ReadVBR(6);
164  unsigned NumElts = ReadVBR(6);
165  for (unsigned i = 0; i != NumElts; ++i)
166  Vals.push_back(ReadVBR64(6));
167  return Code;
168  }
169 
170  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
171 
172  // Read the record code first.
173  assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
174  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
175  unsigned Code;
176  if (CodeOp.isLiteral())
177  Code = CodeOp.getLiteralValue();
178  else {
179  if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
180  CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
181  report_fatal_error("Abbreviation starts with an Array or a Blob");
182  Code = readAbbreviatedField(*this, CodeOp);
183  }
184 
185  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
186  const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
187  if (Op.isLiteral()) {
188  Vals.push_back(Op.getLiteralValue());
189  continue;
190  }
191 
192  if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
194  Vals.push_back(readAbbreviatedField(*this, Op));
195  continue;
196  }
197 
198  if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
199  // Array case. Read the number of elements as a vbr6.
200  unsigned NumElts = ReadVBR(6);
201 
202  // Get the element encoding.
203  if (i + 2 != e)
204  report_fatal_error("Array op not second to last");
205  const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
206  if (!EltEnc.isEncoding())
208  "Array element type has to be an encoding of a type");
209  if (EltEnc.getEncoding() == BitCodeAbbrevOp::Array ||
211  report_fatal_error("Array element type can't be an Array or a Blob");
212 
213  // Read all the elements.
214  for (; NumElts; --NumElts)
215  Vals.push_back(readAbbreviatedField(*this, EltEnc));
216  continue;
217  }
218 
219  assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
220  // Blob case. Read the number of bytes as a vbr6.
221  unsigned NumElts = ReadVBR(6);
222  SkipToFourByteBoundary(); // 32-bit alignment
223 
224  // Figure out where the end of this blob will be including tail padding.
225  size_t CurBitPos = GetCurrentBitNo();
226  size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8;
227 
228  // If this would read off the end of the bitcode file, just set the
229  // record to empty and return.
230  if (!canSkipToPos(NewEnd/8)) {
231  Vals.append(NumElts, 0);
232  NextChar = BitStream->getBitcodeBytes().getExtent();
233  break;
234  }
235 
236  // Otherwise, inform the streamer that we need these bytes in memory.
237  const char *Ptr = (const char*)
238  BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts);
239 
240  // If we can return a reference to the data, do so to avoid copying it.
241  if (Blob) {
242  *Blob = StringRef(Ptr, NumElts);
243  } else {
244  // Otherwise, unpack into Vals with zero extension.
245  for (; NumElts; --NumElts)
246  Vals.push_back((unsigned char)*Ptr++);
247  }
248  // Skip over tail padding.
249  JumpToBit(NewEnd);
250  }
251 
252  return Code;
253 }
254 
255 
257  BitCodeAbbrev *Abbv = new BitCodeAbbrev();
258  unsigned NumOpInfo = ReadVBR(5);
259  for (unsigned i = 0; i != NumOpInfo; ++i) {
260  bool IsLiteral = Read(1);
261  if (IsLiteral) {
262  Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
263  continue;
264  }
265 
268  uint64_t Data = ReadVBR64(5);
269 
270  // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
271  // and vbr(0) as a literal zero. This is decoded the same way, and avoids
272  // a slow path in Read() to have to handle reading zero bits.
273  if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
274  Data == 0) {
275  Abbv->Add(BitCodeAbbrevOp(0));
276  continue;
277  }
278 
279  if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
280  Data > MaxChunkSize)
282  "Fixed or VBR abbrev record with size > MaxChunkData");
283 
284  Abbv->Add(BitCodeAbbrevOp(E, Data));
285  } else
286  Abbv->Add(BitCodeAbbrevOp(E));
287  }
288 
289  if (Abbv->getNumOperandInfos() == 0)
290  report_fatal_error("Abbrev record with no operands");
291  CurAbbrevs.push_back(Abbv);
292 }
293 
295  // If this is the second stream to get to the block info block, skip it.
296  if (BitStream->hasBlockInfoRecords())
297  return SkipBlock();
298 
299  if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
300 
302  BitstreamReader::BlockInfo *CurBlockInfo = nullptr;
303 
304  // Read all the records for this module.
305  while (1) {
307 
308  switch (Entry.Kind) {
309  case llvm::BitstreamEntry::SubBlock: // Handled for us already.
311  return true;
313  return false;
315  // The interesting case.
316  break;
317  }
318 
319  // Read abbrev records, associate them with CurBID.
320  if (Entry.ID == bitc::DEFINE_ABBREV) {
321  if (!CurBlockInfo) return true;
323 
324  // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
325  // appropriate BlockInfo.
326  CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
327  CurAbbrevs.pop_back();
328  continue;
329  }
330 
331  // Read a record.
332  Record.clear();
333  switch (readRecord(Entry.ID, Record)) {
334  default: break; // Default behavior, ignore unknown content.
336  if (Record.size() < 1) return true;
337  CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
338  break;
340  if (!CurBlockInfo) return true;
341  if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
342  std::string Name;
343  for (unsigned i = 0, e = Record.size(); i != e; ++i)
344  Name += (char)Record[i];
345  CurBlockInfo->Name = Name;
346  break;
347  }
349  if (!CurBlockInfo) return true;
350  if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
351  std::string Name;
352  for (unsigned i = 1, e = Record.size(); i != e; ++i)
353  Name += (char)Record[i];
354  CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
355  Name));
356  break;
357  }
358  }
359  }
360 }
361 
void push_back(const T &Elt)
Definition: SmallVector.h:222
const BitCodeAbbrev * getAbbrev(unsigned AbbrevID)
Return the abbreviation for the specified AbbrevId.
BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...
Definition: BitCodes.h:62
virtual uint64_t getExtent() const =0
Returns the size of the region in bytes.
bool isEncoding() const
Definition: BitCodes.h:105
BitCodeAbbrev - This class represents an abbreviation record.
Definition: BitCodes.h:165
static const size_t MaxChunkSize
const BitCodeAbbrevOp & getOperandInfo(unsigned N) const
Definition: BitCodes.h:175
bool hasBlockInfoRecords() const
Return true if we've already read and processed the block info block for this Bitstream.
void Add(const BitCodeAbbrevOp &OpInfo)
Definition: BitCodes.h:179
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
uint64_t GetCurrentBitNo() const
Return the bit # of the bit we are reading.
bool canSkipToPos(size_t pos) const
const BlockInfo * getBlockInfo(unsigned BlockID) const
If there is block info for the specified ID, return it, otherwise return null.
enum llvm::BitstreamEntry::@28 Kind
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
std::vector< std::pair< unsigned, std::string > > RecordNames
uint64_t getEncodingData() const
Definition: BitCodes.h:112
BlockInfo & getOrCreateBlockInfo(unsigned BlockID)
BitstreamEntry advanceSkippingSubblocks(unsigned Flags=0)
This is a convenience function for clients that don't expect any subblocks.
If this flag is used, abbrev entries are returned just like normal records.
bool isLiteral() const
Definition: BitCodes.h:104
bool hasEncodingData() const
Definition: BitCodes.h:117
This represents a position within a bitcode file.
BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
Definition: BitCodes.h:87
static void skipAbbreviatedField(BitstreamCursor &Cursor, const BitCodeAbbrevOp &Op)
uint64_t ReadVBR64(unsigned NumBits)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:416
uint64_t getLiteralValue() const
Definition: BitCodes.h:108
bool SkipBlock()
Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body of this block...
MemoryObject & getBitcodeBytes()
This contains information emitted to BLOCKINFO_BLOCK blocks.
uint32_t ReadVBR(unsigned NumBits)
std::vector< IntrusiveRefCntPtr< BitCodeAbbrev > > Abbrevs
When advancing through a bitstream cursor, each advance can discover a few different kinds of entries...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
unsigned readRecord(unsigned AbbrevID, SmallVectorImpl< uint64_t > &Vals, StringRef *Blob=nullptr)
word_t Read(unsigned NumBits)
void skipRecord(unsigned AbbrevID)
Read the current record and discard it.
DEFINE_ABBREV - Defines an abbrev for the current block.
Definition: BitCodes.h:46
static uint64_t readAbbreviatedField(BitstreamCursor &Cursor, const BitCodeAbbrevOp &Op)
virtual const uint8_t * getPointer(uint64_t address, uint64_t size) const =0
Ensures that the requested data is in memory, and returns a pointer to it.
bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP=nullptr)
Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true if the block has an error...
static char DecodeChar6(unsigned V)
Definition: BitCodes.h:148
unsigned getNumOperandInfos() const
Definition: BitCodes.h:172
void JumpToBit(uint64_t BitNo)
Reset the stream to the specified bit number.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
Encoding getEncoding() const
Definition: BitCodes.h:111