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(); } }