forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			511 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			511 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===//
 | 
						|
//
 | 
						|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | 
						|
// See https://llvm.org/LICENSE.txt for license information.
 | 
						|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "llvm/Bitstream/BitstreamReader.h"
 | 
						|
#include "llvm/ADT/StringRef.h"
 | 
						|
#include <cassert>
 | 
						|
#include <string>
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//  BitstreamCursor implementation
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
/// Having read the ENTER_SUBBLOCK abbrevid, enter the block.
 | 
						|
Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {
 | 
						|
  // Save the current block's state on BlockScope.
 | 
						|
  BlockScope.push_back(Block(CurCodeSize));
 | 
						|
  BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
 | 
						|
 | 
						|
  // Add the abbrevs specific to this block to the CurAbbrevs list.
 | 
						|
  if (BlockInfo) {
 | 
						|
    if (const BitstreamBlockInfo::BlockInfo *Info =
 | 
						|
            BlockInfo->getBlockInfo(BlockID)) {
 | 
						|
      CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(),
 | 
						|
                        Info->Abbrevs.end());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Get the codesize of this block.
 | 
						|
  Expected<uint32_t> MaybeVBR = ReadVBR(bitc::CodeLenWidth);
 | 
						|
  if (!MaybeVBR)
 | 
						|
    return MaybeVBR.takeError();
 | 
						|
  CurCodeSize = MaybeVBR.get();
 | 
						|
 | 
						|
  if (CurCodeSize > MaxChunkSize)
 | 
						|
    return llvm::createStringError(
 | 
						|
        std::errc::illegal_byte_sequence,
 | 
						|
        "can't read more than %zu at a time, trying to read %u", +MaxChunkSize,
 | 
						|
        CurCodeSize);
 | 
						|
 | 
						|
  SkipToFourByteBoundary();
 | 
						|
  Expected<word_t> MaybeNum = Read(bitc::BlockSizeWidth);
 | 
						|
  if (!MaybeNum)
 | 
						|
    return MaybeNum.takeError();
 | 
						|
  word_t NumWords = MaybeNum.get();
 | 
						|
  if (NumWordsP)
 | 
						|
    *NumWordsP = NumWords;
 | 
						|
 | 
						|
  if (CurCodeSize == 0)
 | 
						|
    return llvm::createStringError(
 | 
						|
        std::errc::illegal_byte_sequence,
 | 
						|
        "can't enter sub-block: current code size is 0");
 | 
						|
  if (AtEndOfStream())
 | 
						|
    return llvm::createStringError(
 | 
						|
        std::errc::illegal_byte_sequence,
 | 
						|
        "can't enter sub block: already at end of stream");
 | 
						|
 | 
						|
  return Error::success();
 | 
						|
}
 | 
						|
 | 
						|
static Expected<uint64_t> readAbbreviatedField(BitstreamCursor &Cursor,
 | 
						|
                                               const BitCodeAbbrevOp &Op) {
 | 
						|
  assert(!Op.isLiteral() && "Not to be used with literals!");
 | 
						|
 | 
						|
  // Decode the value as we are commanded.
 | 
						|
  switch (Op.getEncoding()) {
 | 
						|
  case BitCodeAbbrevOp::Array:
 | 
						|
  case BitCodeAbbrevOp::Blob:
 | 
						|
    llvm_unreachable("Should not reach here");
 | 
						|
  case BitCodeAbbrevOp::Fixed:
 | 
						|
    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
 | 
						|
    return Cursor.Read((unsigned)Op.getEncodingData());
 | 
						|
  case BitCodeAbbrevOp::VBR:
 | 
						|
    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
 | 
						|
    return Cursor.ReadVBR64((unsigned)Op.getEncodingData());
 | 
						|
  case BitCodeAbbrevOp::Char6:
 | 
						|
    if (Expected<unsigned> Res = Cursor.Read(6))
 | 
						|
      return BitCodeAbbrevOp::DecodeChar6(Res.get());
 | 
						|
    else
 | 
						|
      return Res.takeError();
 | 
						|
  }
 | 
						|
  llvm_unreachable("invalid abbreviation encoding");
 | 
						|
}
 | 
						|
 | 
						|
static Error skipAbbreviatedField(BitstreamCursor &Cursor,
 | 
						|
                                  const BitCodeAbbrevOp &Op) {
 | 
						|
  assert(!Op.isLiteral() && "Not to be used with literals!");
 | 
						|
 | 
						|
  // Decode the value as we are commanded.
 | 
						|
  switch (Op.getEncoding()) {
 | 
						|
  case BitCodeAbbrevOp::Array:
 | 
						|
  case BitCodeAbbrevOp::Blob:
 | 
						|
    llvm_unreachable("Should not reach here");
 | 
						|
  case BitCodeAbbrevOp::Fixed:
 | 
						|
    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
 | 
						|
    if (Expected<unsigned> Res = Cursor.Read((unsigned)Op.getEncodingData()))
 | 
						|
      break;
 | 
						|
    else
 | 
						|
      return Res.takeError();
 | 
						|
  case BitCodeAbbrevOp::VBR:
 | 
						|
    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);
 | 
						|
    if (Expected<uint64_t> Res =
 | 
						|
            Cursor.ReadVBR64((unsigned)Op.getEncodingData()))
 | 
						|
      break;
 | 
						|
    else
 | 
						|
      return Res.takeError();
 | 
						|
  case BitCodeAbbrevOp::Char6:
 | 
						|
    if (Expected<unsigned> Res = Cursor.Read(6))
 | 
						|
      break;
 | 
						|
    else
 | 
						|
      return Res.takeError();
 | 
						|
  }
 | 
						|
  return ErrorSuccess();
 | 
						|
}
 | 
						|
 | 
						|
/// skipRecord - Read the current record and discard it.
 | 
						|
Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) {
 | 
						|
  // Skip unabbreviated records by reading past their entries.
 | 
						|
  if (AbbrevID == bitc::UNABBREV_RECORD) {
 | 
						|
    Expected<uint32_t> MaybeCode = ReadVBR(6);
 | 
						|
    if (!MaybeCode)
 | 
						|
      return MaybeCode.takeError();
 | 
						|
    unsigned Code = MaybeCode.get();
 | 
						|
    Expected<uint32_t> MaybeVBR = ReadVBR(6);
 | 
						|
    if (!MaybeVBR)
 | 
						|
      return MaybeVBR.get();
 | 
						|
    unsigned NumElts = MaybeVBR.get();
 | 
						|
    for (unsigned i = 0; i != NumElts; ++i)
 | 
						|
      if (Expected<uint64_t> Res = ReadVBR64(6))
 | 
						|
        ; // Skip!
 | 
						|
      else
 | 
						|
        return Res.takeError();
 | 
						|
    return Code;
 | 
						|
  }
 | 
						|
 | 
						|
  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
 | 
						|
  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
 | 
						|
  unsigned Code;
 | 
						|
  if (CodeOp.isLiteral())
 | 
						|
    Code = CodeOp.getLiteralValue();
 | 
						|
  else {
 | 
						|
    if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
 | 
						|
        CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
 | 
						|
      return llvm::createStringError(
 | 
						|
          std::errc::illegal_byte_sequence,
 | 
						|
          "Abbreviation starts with an Array or a Blob");
 | 
						|
    Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp);
 | 
						|
    if (!MaybeCode)
 | 
						|
      return MaybeCode.takeError();
 | 
						|
    Code = MaybeCode.get();
 | 
						|
  }
 | 
						|
 | 
						|
  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i < e; ++i) {
 | 
						|
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
 | 
						|
    if (Op.isLiteral())
 | 
						|
      continue;
 | 
						|
 | 
						|
    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
 | 
						|
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
 | 
						|
      if (Error Err = skipAbbreviatedField(*this, Op))
 | 
						|
        return std::move(Err);
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
 | 
						|
      // Array case.  Read the number of elements as a vbr6.
 | 
						|
      Expected<uint32_t> MaybeNum = ReadVBR(6);
 | 
						|
      if (!MaybeNum)
 | 
						|
        return MaybeNum.takeError();
 | 
						|
      unsigned NumElts = MaybeNum.get();
 | 
						|
 | 
						|
      // Get the element encoding.
 | 
						|
      assert(i+2 == e && "array op not second to last?");
 | 
						|
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
 | 
						|
 | 
						|
      // Read all the elements.
 | 
						|
      // Decode the value as we are commanded.
 | 
						|
      switch (EltEnc.getEncoding()) {
 | 
						|
      default:
 | 
						|
        report_fatal_error("Array element type can't be an Array or a Blob");
 | 
						|
      case BitCodeAbbrevOp::Fixed:
 | 
						|
        assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
 | 
						|
        if (Error Err = JumpToBit(GetCurrentBitNo() +
 | 
						|
                                  NumElts * EltEnc.getEncodingData()))
 | 
						|
          return std::move(Err);
 | 
						|
        break;
 | 
						|
      case BitCodeAbbrevOp::VBR:
 | 
						|
        assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize);
 | 
						|
        for (; NumElts; --NumElts)
 | 
						|
          if (Expected<uint64_t> Res =
 | 
						|
                  ReadVBR64((unsigned)EltEnc.getEncodingData()))
 | 
						|
            ; // Skip!
 | 
						|
          else
 | 
						|
            return Res.takeError();
 | 
						|
        break;
 | 
						|
      case BitCodeAbbrevOp::Char6:
 | 
						|
        if (Error Err = JumpToBit(GetCurrentBitNo() + NumElts * 6))
 | 
						|
          return std::move(Err);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
 | 
						|
    // Blob case.  Read the number of bytes as a vbr6.
 | 
						|
    Expected<uint32_t> MaybeNum = ReadVBR(6);
 | 
						|
    if (!MaybeNum)
 | 
						|
      return MaybeNum.takeError();
 | 
						|
    unsigned NumElts = MaybeNum.get();
 | 
						|
    SkipToFourByteBoundary();  // 32-bit alignment
 | 
						|
 | 
						|
    // Figure out where the end of this blob will be including tail padding.
 | 
						|
    size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8;
 | 
						|
 | 
						|
    // If this would read off the end of the bitcode file, just set the
 | 
						|
    // record to empty and return.
 | 
						|
    if (!canSkipToPos(NewEnd/8)) {
 | 
						|
      skipToEnd();
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    // Skip over the blob.
 | 
						|
    if (Error Err = JumpToBit(NewEnd))
 | 
						|
      return std::move(Err);
 | 
						|
  }
 | 
						|
  return Code;
 | 
						|
}
 | 
						|
 | 
						|
Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID,
 | 
						|
                                               SmallVectorImpl<uint64_t> &Vals,
 | 
						|
                                               StringRef *Blob) {
 | 
						|
  if (AbbrevID == bitc::UNABBREV_RECORD) {
 | 
						|
    Expected<uint32_t> MaybeCode = ReadVBR(6);
 | 
						|
    if (!MaybeCode)
 | 
						|
      return MaybeCode.takeError();
 | 
						|
    uint32_t Code = MaybeCode.get();
 | 
						|
    Expected<uint32_t> MaybeNumElts = ReadVBR(6);
 | 
						|
    if (!MaybeNumElts)
 | 
						|
      return MaybeNumElts.takeError();
 | 
						|
    uint32_t NumElts = MaybeNumElts.get();
 | 
						|
 | 
						|
    for (unsigned i = 0; i != NumElts; ++i)
 | 
						|
      if (Expected<uint64_t> MaybeVal = ReadVBR64(6))
 | 
						|
        Vals.push_back(MaybeVal.get());
 | 
						|
      else
 | 
						|
        return MaybeVal.takeError();
 | 
						|
    return Code;
 | 
						|
  }
 | 
						|
 | 
						|
  const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
 | 
						|
 | 
						|
  // Read the record code first.
 | 
						|
  assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?");
 | 
						|
  const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0);
 | 
						|
  unsigned Code;
 | 
						|
  if (CodeOp.isLiteral())
 | 
						|
    Code = CodeOp.getLiteralValue();
 | 
						|
  else {
 | 
						|
    if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array ||
 | 
						|
        CodeOp.getEncoding() == BitCodeAbbrevOp::Blob)
 | 
						|
      report_fatal_error("Abbreviation starts with an Array or a Blob");
 | 
						|
    if (Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp))
 | 
						|
      Code = MaybeCode.get();
 | 
						|
    else
 | 
						|
      return MaybeCode.takeError();
 | 
						|
  }
 | 
						|
 | 
						|
  for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {
 | 
						|
    const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
 | 
						|
    if (Op.isLiteral()) {
 | 
						|
      Vals.push_back(Op.getLiteralValue());
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Op.getEncoding() != BitCodeAbbrevOp::Array &&
 | 
						|
        Op.getEncoding() != BitCodeAbbrevOp::Blob) {
 | 
						|
      if (Expected<uint64_t> MaybeVal = readAbbreviatedField(*this, Op))
 | 
						|
        Vals.push_back(MaybeVal.get());
 | 
						|
      else
 | 
						|
        return MaybeVal.takeError();
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
 | 
						|
      // Array case.  Read the number of elements as a vbr6.
 | 
						|
      Expected<uint32_t> MaybeNumElts = ReadVBR(6);
 | 
						|
      if (!MaybeNumElts)
 | 
						|
        return MaybeNumElts.takeError();
 | 
						|
      uint32_t NumElts = MaybeNumElts.get();
 | 
						|
 | 
						|
      // Get the element encoding.
 | 
						|
      if (i + 2 != e)
 | 
						|
        report_fatal_error("Array op not second to last");
 | 
						|
      const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
 | 
						|
      if (!EltEnc.isEncoding())
 | 
						|
        report_fatal_error(
 | 
						|
            "Array element type has to be an encoding of a type");
 | 
						|
 | 
						|
      // Read all the elements.
 | 
						|
      switch (EltEnc.getEncoding()) {
 | 
						|
      default:
 | 
						|
        report_fatal_error("Array element type can't be an Array or a Blob");
 | 
						|
      case BitCodeAbbrevOp::Fixed:
 | 
						|
        for (; NumElts; --NumElts)
 | 
						|
          if (Expected<SimpleBitstreamCursor::word_t> MaybeVal =
 | 
						|
                  Read((unsigned)EltEnc.getEncodingData()))
 | 
						|
            Vals.push_back(MaybeVal.get());
 | 
						|
          else
 | 
						|
            return MaybeVal.takeError();
 | 
						|
        break;
 | 
						|
      case BitCodeAbbrevOp::VBR:
 | 
						|
        for (; NumElts; --NumElts)
 | 
						|
          if (Expected<uint64_t> MaybeVal =
 | 
						|
                  ReadVBR64((unsigned)EltEnc.getEncodingData()))
 | 
						|
            Vals.push_back(MaybeVal.get());
 | 
						|
          else
 | 
						|
            return MaybeVal.takeError();
 | 
						|
        break;
 | 
						|
      case BitCodeAbbrevOp::Char6:
 | 
						|
        for (; NumElts; --NumElts)
 | 
						|
          if (Expected<SimpleBitstreamCursor::word_t> MaybeVal = Read(6))
 | 
						|
            Vals.push_back(BitCodeAbbrevOp::DecodeChar6(MaybeVal.get()));
 | 
						|
          else
 | 
						|
            return MaybeVal.takeError();
 | 
						|
      }
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    assert(Op.getEncoding() == BitCodeAbbrevOp::Blob);
 | 
						|
    // Blob case.  Read the number of bytes as a vbr6.
 | 
						|
    Expected<uint32_t> MaybeNumElts = ReadVBR(6);
 | 
						|
    if (!MaybeNumElts)
 | 
						|
      return MaybeNumElts.takeError();
 | 
						|
    uint32_t NumElts = MaybeNumElts.get();
 | 
						|
    SkipToFourByteBoundary();  // 32-bit alignment
 | 
						|
 | 
						|
    // Figure out where the end of this blob will be including tail padding.
 | 
						|
    size_t CurBitPos = GetCurrentBitNo();
 | 
						|
    size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8;
 | 
						|
 | 
						|
    // If this would read off the end of the bitcode file, just set the
 | 
						|
    // record to empty and return.
 | 
						|
    if (!canSkipToPos(NewEnd/8)) {
 | 
						|
      Vals.append(NumElts, 0);
 | 
						|
      skipToEnd();
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    // Otherwise, inform the streamer that we need these bytes in memory.  Skip
 | 
						|
    // over tail padding first, in case jumping to NewEnd invalidates the Blob
 | 
						|
    // pointer.
 | 
						|
    if (Error Err = JumpToBit(NewEnd))
 | 
						|
      return std::move(Err);
 | 
						|
    const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts);
 | 
						|
 | 
						|
    // If we can return a reference to the data, do so to avoid copying it.
 | 
						|
    if (Blob) {
 | 
						|
      *Blob = StringRef(Ptr, NumElts);
 | 
						|
    } else {
 | 
						|
      // Otherwise, unpack into Vals with zero extension.
 | 
						|
      for (; NumElts; --NumElts)
 | 
						|
        Vals.push_back((unsigned char)*Ptr++);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return Code;
 | 
						|
}
 | 
						|
 | 
						|
Error BitstreamCursor::ReadAbbrevRecord() {
 | 
						|
  auto Abbv = std::make_shared<BitCodeAbbrev>();
 | 
						|
  Expected<uint32_t> MaybeNumOpInfo = ReadVBR(5);
 | 
						|
  if (!MaybeNumOpInfo)
 | 
						|
    return MaybeNumOpInfo.takeError();
 | 
						|
  unsigned NumOpInfo = MaybeNumOpInfo.get();
 | 
						|
  for (unsigned i = 0; i != NumOpInfo; ++i) {
 | 
						|
    Expected<word_t> MaybeIsLiteral = Read(1);
 | 
						|
    if (!MaybeIsLiteral)
 | 
						|
      return MaybeIsLiteral.takeError();
 | 
						|
    bool IsLiteral = MaybeIsLiteral.get();
 | 
						|
    if (IsLiteral) {
 | 
						|
      Expected<uint64_t> MaybeOp = ReadVBR64(8);
 | 
						|
      if (!MaybeOp)
 | 
						|
        return MaybeOp.takeError();
 | 
						|
      Abbv->Add(BitCodeAbbrevOp(MaybeOp.get()));
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    Expected<word_t> MaybeEncoding = Read(3);
 | 
						|
    if (!MaybeEncoding)
 | 
						|
      return MaybeEncoding.takeError();
 | 
						|
    BitCodeAbbrevOp::Encoding E =
 | 
						|
        (BitCodeAbbrevOp::Encoding)MaybeEncoding.get();
 | 
						|
    if (BitCodeAbbrevOp::hasEncodingData(E)) {
 | 
						|
      Expected<uint64_t> MaybeData = ReadVBR64(5);
 | 
						|
      if (!MaybeData)
 | 
						|
        return MaybeData.takeError();
 | 
						|
      uint64_t Data = MaybeData.get();
 | 
						|
 | 
						|
      // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
 | 
						|
      // and vbr(0) as a literal zero.  This is decoded the same way, and avoids
 | 
						|
      // a slow path in Read() to have to handle reading zero bits.
 | 
						|
      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
 | 
						|
          Data == 0) {
 | 
						|
        Abbv->Add(BitCodeAbbrevOp(0));
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
 | 
						|
          Data > MaxChunkSize)
 | 
						|
        report_fatal_error(
 | 
						|
            "Fixed or VBR abbrev record with size > MaxChunkData");
 | 
						|
 | 
						|
      Abbv->Add(BitCodeAbbrevOp(E, Data));
 | 
						|
    } else
 | 
						|
      Abbv->Add(BitCodeAbbrevOp(E));
 | 
						|
  }
 | 
						|
 | 
						|
  if (Abbv->getNumOperandInfos() == 0)
 | 
						|
    report_fatal_error("Abbrev record with no operands");
 | 
						|
  CurAbbrevs.push_back(std::move(Abbv));
 | 
						|
 | 
						|
  return Error::success();
 | 
						|
}
 | 
						|
 | 
						|
Expected<Optional<BitstreamBlockInfo>>
 | 
						|
BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) {
 | 
						|
  if (llvm::Error Err = EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID))
 | 
						|
    return std::move(Err);
 | 
						|
 | 
						|
  BitstreamBlockInfo NewBlockInfo;
 | 
						|
 | 
						|
  SmallVector<uint64_t, 64> Record;
 | 
						|
  BitstreamBlockInfo::BlockInfo *CurBlockInfo = nullptr;
 | 
						|
 | 
						|
  // Read all the records for this module.
 | 
						|
  while (true) {
 | 
						|
    Expected<BitstreamEntry> MaybeEntry =
 | 
						|
        advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs);
 | 
						|
    if (!MaybeEntry)
 | 
						|
      return MaybeEntry.takeError();
 | 
						|
    BitstreamEntry Entry = MaybeEntry.get();
 | 
						|
 | 
						|
    switch (Entry.Kind) {
 | 
						|
    case llvm::BitstreamEntry::SubBlock: // Handled for us already.
 | 
						|
    case llvm::BitstreamEntry::Error:
 | 
						|
      return None;
 | 
						|
    case llvm::BitstreamEntry::EndBlock:
 | 
						|
      return std::move(NewBlockInfo);
 | 
						|
    case llvm::BitstreamEntry::Record:
 | 
						|
      // The interesting case.
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    // Read abbrev records, associate them with CurBID.
 | 
						|
    if (Entry.ID == bitc::DEFINE_ABBREV) {
 | 
						|
      if (!CurBlockInfo) return None;
 | 
						|
      if (Error Err = ReadAbbrevRecord())
 | 
						|
        return std::move(Err);
 | 
						|
 | 
						|
      // ReadAbbrevRecord installs the abbrev in CurAbbrevs.  Move it to the
 | 
						|
      // appropriate BlockInfo.
 | 
						|
      CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back()));
 | 
						|
      CurAbbrevs.pop_back();
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    // Read a record.
 | 
						|
    Record.clear();
 | 
						|
    Expected<unsigned> MaybeBlockInfo = readRecord(Entry.ID, Record);
 | 
						|
    if (!MaybeBlockInfo)
 | 
						|
      return MaybeBlockInfo.takeError();
 | 
						|
    switch (MaybeBlockInfo.get()) {
 | 
						|
    default:
 | 
						|
      break; // Default behavior, ignore unknown content.
 | 
						|
    case bitc::BLOCKINFO_CODE_SETBID:
 | 
						|
      if (Record.size() < 1)
 | 
						|
        return None;
 | 
						|
      CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]);
 | 
						|
      break;
 | 
						|
    case bitc::BLOCKINFO_CODE_BLOCKNAME: {
 | 
						|
      if (!CurBlockInfo)
 | 
						|
        return None;
 | 
						|
      if (!ReadBlockInfoNames)
 | 
						|
        break; // Ignore name.
 | 
						|
      std::string Name;
 | 
						|
      for (unsigned i = 0, e = Record.size(); i != e; ++i)
 | 
						|
        Name += (char)Record[i];
 | 
						|
      CurBlockInfo->Name = Name;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
      case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
 | 
						|
        if (!CurBlockInfo) return None;
 | 
						|
        if (!ReadBlockInfoNames)
 | 
						|
          break; // Ignore name.
 | 
						|
        std::string Name;
 | 
						|
        for (unsigned i = 1, e = Record.size(); i != e; ++i)
 | 
						|
          Name += (char)Record[i];
 | 
						|
        CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
 | 
						|
                                                           Name));
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      }
 | 
						|
  }
 | 
						|
}
 |