void NaClBitstreamCursor::ReadAbbrevRecord(bool IsLocal,
                                           NaClAbbrevListener *Listener) {
  NaClBitCodeAbbrev *Abbv = BlockScope.back().appendLocalCreate();
  unsigned NumOpInfo = ReadVBR(5);
  if (Listener) Listener->Values.push_back(NumOpInfo);
  for (unsigned i = 0; i != NumOpInfo; ++i) {
    bool IsLiteral = Read(1) ? true : false;
    if (Listener) Listener->Values.push_back(IsLiteral);
    if (IsLiteral) {
      uint64_t Value = ReadVBR64(8);
      if (Listener) Listener->Values.push_back(Value);
      Abbv->Add(NaClBitCodeAbbrevOp(Value));
      continue;
    }
    NaClBitCodeAbbrevOp::Encoding E = getEncoding(Read(3));
    if (Listener) Listener->Values.push_back(E);
    if (NaClBitCodeAbbrevOp::hasValue(E)) {
      unsigned Data = ReadVBR64(5);
      if (Listener) Listener->Values.push_back(Data);

      // 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 == NaClBitCodeAbbrevOp::Fixed || E == NaClBitCodeAbbrevOp::VBR) &&
          Data == 0) {
        if (Listener) Listener->Values.push_back(0);
        Abbv->Add(NaClBitCodeAbbrevOp(0));
        continue;
      }
      if (!NaClBitCodeAbbrevOp::isValid(E, Data)) {
        std::string Buffer;
        raw_string_ostream StrBuf(Buffer);
        StrBuf << "Invalid abbreviation encoding ("
               << NaClBitCodeAbbrevOp::getEncodingName(E)
               << ", " << Data << ")";
        ErrHandler->Fatal(StrBuf.str());
      }
      Abbv->Add(NaClBitCodeAbbrevOp(E, Data));
    } else {
      if (!NaClBitCodeAbbrevOp::isValid(E)) {
        std::string Buffer;
        raw_string_ostream StrBuf(Buffer);
        StrBuf << "Invalid abbreviation encoding ("
               << NaClBitCodeAbbrevOp::getEncodingName(E) << ")";
        ErrHandler->Fatal(StrBuf.str());
      }
      Abbv->Add(NaClBitCodeAbbrevOp(E));
    }
  }
  SkipToByteBoundaryIfAligned();
  if (!Abbv->isValid())
    ErrHandler->Fatal("Invalid abbreviation specified in bitcode file");
  if (Listener) {
    Listener->ProcessAbbreviation(Abbv, IsLocal);
    // Reset record information of the listener.
    Listener->Values.clear();
    Listener->StartBit = GetCurrentBitNo();
  }
}