void NaClBitstreamCursor::ReadAbbrevRecord() { NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); unsigned NumOpInfo = ReadVBR(5); for (unsigned i = 0; i != NumOpInfo; ++i) { bool IsLiteral = Read(1) ? true : false; if (IsLiteral) { Abbv->Add(NaClBitCodeAbbrevOp(ReadVBR64(8))); continue; } NaClBitCodeAbbrevOp::Encoding E = (NaClBitCodeAbbrevOp::Encoding)Read(3); if (NaClBitCodeAbbrevOp::hasEncodingData(E)) { unsigned Data = ReadVBR64(5); // 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) { Abbv->Add(NaClBitCodeAbbrevOp(0)); continue; } Abbv->Add(NaClBitCodeAbbrevOp(E, Data)); } else Abbv->Add(NaClBitCodeAbbrevOp(E)); } CurAbbrevs.push_back(Abbv); }
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(); } }
NaClBitCodeAbbrev *NaClBitcodeMunger::buildAbbrev( unsigned RecordCode, SmallVectorImpl<uint64_t> &Values) { NaClBitCodeAbbrev *Abbrev = new NaClBitCodeAbbrev(); size_t Index = 0; if (Values.empty()) { Fatal() << "Empty abbreviation record not allowed\n"; ReportFatalError(); } size_t NumAbbreviations = Values[Index++]; if (NumAbbreviations == 0) { Fatal() << "Abbreviation must contain at least one operator\n"; ReportFatalError(); } for (size_t Count = 0; Count < NumAbbreviations; ++Count) { if (Index >= Values.size()) { Fatal() << "Malformed abbreviation found. Expects " << NumAbbreviations << " operands. Found: " << Count << "\n"; ReportFatalError(); } switch (Values[Index++]) { case 1: if (Index >= Values.size()) { Fatal() << "Malformed literal abbreviation.\n"; ReportFatalError(); } Abbrev->Add(NaClBitCodeAbbrevOp(Values[Index++])); break; case 0: { if (Index >= Values.size()) { Fatal() << "Malformed abbreviation found.\n"; ReportFatalError(); } unsigned Kind = Values[Index++]; switch (Kind) { case NaClBitCodeAbbrevOp::Fixed: if (Index >= Values.size()) { Fatal() << "Malformed fixed abbreviation found.\n"; ReportFatalError(); } Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, Values[Index++])); break; case NaClBitCodeAbbrevOp::VBR: if (Index >= Values.size()) { Fatal() << "Malformed vbr abbreviation found.\n"; ReportFatalError(); } Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, Values[Index++])); break; case NaClBitCodeAbbrevOp::Array: if (Index >= Values.size()) { Fatal() << "Malformed array abbreviation found.\n"; ReportFatalError(); } Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); break; case NaClBitCodeAbbrevOp::Char6: Abbrev->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); break; default: Fatal() << "Unknown abbreviation kind. Found: " << Kind << "\n"; ReportFatalError(); } break; } default: Fatal() << "Error: Bad literal flag in abbreviation. Found: " << Values[Index]; ReportFatalError(); } } return Abbrev; }
// Emit blockinfo, which defines the standard abbreviations etc. static void WriteBlockInfo(const NaClValueEnumerator &VE, NaClBitstreamWriter &Stream) { // We only want to emit block info records for blocks that have multiple // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK. // Other blocks can define their abbrevs inline. Stream.EnterBlockInfoBlock(); { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 3)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 8)); if (Stream.EmitBlockInfoAbbrev(naclbitc::VALUE_SYMTAB_BLOCK_ID, Abbv) != VST_ENTRY_8_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // 7-bit fixed width VST_ENTRY strings. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::VST_CODE_ENTRY)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 7)); if (Stream.EmitBlockInfoAbbrev(naclbitc::VALUE_SYMTAB_BLOCK_ID, Abbv) != VST_ENTRY_7_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // 6-bit char6 VST_ENTRY strings. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::VST_CODE_ENTRY)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); if (Stream.EmitBlockInfoAbbrev(naclbitc::VALUE_SYMTAB_BLOCK_ID, Abbv) != VST_ENTRY_6_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // 6-bit char6 VST_BBENTRY strings. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::VST_CODE_BBENTRY)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Char6)); if (Stream.EmitBlockInfoAbbrev(naclbitc::VALUE_SYMTAB_BLOCK_ID, Abbv) != VST_BBENTRY_6_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // SETTYPE abbrev for CONSTANTS_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_SETTYPE)); Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); if (Stream.EmitBlockInfoAbbrev(naclbitc::CONSTANTS_BLOCK_ID, Abbv) != CONSTANTS_SETTYPE_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INTEGER abbrev for CONSTANTS_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_INTEGER)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); if (Stream.EmitBlockInfoAbbrev(naclbitc::CONSTANTS_BLOCK_ID, Abbv) != CONSTANTS_INTEGER_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INTEGER_ZERO abbrev for CONSTANTS_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_INTEGER)); Abbv->Add(NaClBitCodeAbbrevOp(0)); if (Stream.EmitBlockInfoAbbrev(naclbitc::CONSTANTS_BLOCK_ID, Abbv) != CONSTANTS_INTEGER_ZERO_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // FLOAT abbrev for CONSTANTS_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::CST_CODE_FLOAT)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); if (Stream.EmitBlockInfoAbbrev(naclbitc::CONSTANTS_BLOCK_ID, Abbv) != CONSTANTS_FLOAT_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } // FIXME: This should only use space for first class types! { // INST_LOAD abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_LOAD)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // Ptr Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 4)); // Align // Note: The vast majority of load operations are only on integers // and floats. In addition, no function types are allowed. In // addition, the type IDs have been sorted based on usage, moving // type IDs associated integers and floats to very low // indices. Hence, we assume that we can use a smaller width for // the typecast. Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 4)); // TypeCast if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_LOAD_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_BINOP abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_BINOP)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // LHS Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // RHS Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 4)); // opc if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_BINOP_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_CAST abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_CAST)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // OpVal Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); // dest ty Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 4)); // opc if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_CAST_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_RET abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_RET)); if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_RET_VOID_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_RET abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_RET)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // ValID if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_RET_VAL_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_UNREACHABLE)); if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_FORWARDTYPEREF abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_FORWARDTYPEREF)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_FORWARDTYPEREF_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // INST_STORE abbrev for FUNCTION_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::FUNC_CODE_INST_STORE)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // Ptr Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); // Value Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 4)); // Align if (Stream.EmitBlockInfoAbbrev(naclbitc::FUNCTION_BLOCK_ID, Abbv) != FUNCTION_INST_STORE_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // VAR abbrev for GLOBALVAR_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::GLOBALVAR_VAR)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 1)); if (Stream.EmitBlockInfoAbbrev(naclbitc::GLOBALVAR_BLOCK_ID, Abbv) != GLOBALVAR_VAR_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // COMPOUND abbrev for GLOBALVAR_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::GLOBALVAR_COMPOUND)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); if (Stream.EmitBlockInfoAbbrev(naclbitc::GLOBALVAR_BLOCK_ID, Abbv) != GLOBALVAR_COMPOUND_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // ZEROFILL abbrev for GLOBALVAR_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::GLOBALVAR_ZEROFILL)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 8)); if (Stream.EmitBlockInfoAbbrev(naclbitc::GLOBALVAR_BLOCK_ID, Abbv) != GLOBALVAR_ZEROFILL_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // DATA abbrev for GLOBALVAR_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::GLOBALVAR_DATA)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 8)); if (Stream.EmitBlockInfoAbbrev(naclbitc::GLOBALVAR_BLOCK_ID, Abbv) != GLOBALVAR_DATA_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // RELOC abbrev for GLOBALVAR_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::GLOBALVAR_RELOC)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); if (Stream.EmitBlockInfoAbbrev(naclbitc::GLOBALVAR_BLOCK_ID, Abbv) != GLOBALVAR_RELOC_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } { // RELOC_WITH_ADDEND_ABBREV abbrev for GLOBALVAR_BLOCK. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::GLOBALVAR_RELOC)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::VBR, 6)); if (Stream.EmitBlockInfoAbbrev( naclbitc::GLOBALVAR_BLOCK_ID, Abbv) != GLOBALVAR_RELOC_WITH_ADDEND_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } Stream.ExitBlock(); }
/// WriteTypeTable - Write out the type table for a module. static void WriteTypeTable(const NaClValueEnumerator &VE, NaClBitstreamWriter &Stream) { DEBUG(dbgs() << "-> WriteTypeTable\n"); const NaClValueEnumerator::TypeList &TypeList = VE.getTypes(); Stream.EnterSubblock(naclbitc::TYPE_BLOCK_ID_NEW, TYPE_MAX_ABBREV); SmallVector<uint64_t, 64> TypeVals; // Abbrev for TYPE_CODE_FUNCTION. NaClBitCodeAbbrev *Abbv = new NaClBitCodeAbbrev(); Abbv->Add(NaClBitCodeAbbrevOp(naclbitc::TYPE_CODE_FUNCTION)); Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Fixed, 1)); // isvararg Abbv->Add(NaClBitCodeAbbrevOp(NaClBitCodeAbbrevOp::Array)); Abbv->Add(NaClBitCodeAbbrevOp(TypeIdEncoding, TypeIdNumBits)); if (TYPE_FUNCTION_ABBREV != Stream.EmitAbbrev(Abbv)) llvm_unreachable("Unexpected abbrev ordering!"); // Emit an entry count so the reader can reserve space. TypeVals.push_back(TypeList.size()); Stream.EmitRecord(naclbitc::TYPE_CODE_NUMENTRY, TypeVals); TypeVals.clear(); // Loop over all of the types, emitting each in turn. for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { Type *T = TypeList[i]; int AbbrevToUse = 0; unsigned Code = 0; switch (T->getTypeID()) { default: llvm_unreachable("Unknown type!"); case Type::VoidTyID: Code = naclbitc::TYPE_CODE_VOID; break; case Type::FloatTyID: Code = naclbitc::TYPE_CODE_FLOAT; break; case Type::DoubleTyID: Code = naclbitc::TYPE_CODE_DOUBLE; break; case Type::IntegerTyID: // INTEGER: [width] Code = naclbitc::TYPE_CODE_INTEGER; TypeVals.push_back(cast<IntegerType>(T)->getBitWidth()); break; case Type::VectorTyID: { VectorType *VT = cast<VectorType>(T); // VECTOR [numelts, eltty] Code = naclbitc::TYPE_CODE_VECTOR; TypeVals.push_back(VT->getNumElements()); TypeVals.push_back(VE.getTypeID(VT->getElementType())); break; } case Type::FunctionTyID: { FunctionType *FT = cast<FunctionType>(T); // FUNCTION: [isvararg, retty, paramty x N] Code = naclbitc::TYPE_CODE_FUNCTION; TypeVals.push_back(FT->isVarArg()); TypeVals.push_back(VE.getTypeID(FT->getReturnType())); for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) TypeVals.push_back(VE.getTypeID(FT->getParamType(i))); AbbrevToUse = TYPE_FUNCTION_ABBREV; break; } case Type::StructTyID: report_fatal_error("Struct types are not supported in PNaCl bitcode"); case Type::ArrayTyID: report_fatal_error("Array types are not supported in PNaCl bitcode"); } // Emit the finished record. Stream.EmitRecord(Code, TypeVals, AbbrevToUse); TypeVals.clear(); } Stream.ExitBlock(); DEBUG(dbgs() << "<- WriteTypeTable\n"); }