Index: include/llvm/Bitcode/BitstreamWriter.h =================================================================== --- include/llvm/Bitcode/BitstreamWriter.h +++ include/llvm/Bitcode/BitstreamWriter.h @@ -287,9 +287,12 @@ /// emission code. If BlobData is non-null, then it specifies an array of /// data that should be emitted as part of the Blob or Array operand that is /// known to exist at the end of the record. + /// An optional Code can be passed separately as a convenience to avoid + /// having EmitRecord() performing a push_front on Vals. template void EmitRecordWithAbbrevImpl(unsigned Abbrev, const ArrayRef &Vals, - StringRef Blob) { + StringRef Blob, + Optional Code = Optional()) { const char *BlobData = Blob.data(); unsigned BlobLen = (unsigned) Blob.size(); unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV; @@ -299,8 +302,24 @@ EmitCode(Abbrev); unsigned RecordIdx = 0; - for (unsigned i = 0, e = static_cast(Abbv->getNumOperandInfos()); - i != e; ++i) { + unsigned i = 0, e = static_cast(Abbv->getNumOperandInfos()); + + // If a "Code" is passed in separately, emit it first. + if (Code) { + assert(e && "Expected non-empty abbreviation"); + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i++); + assert(!Op.getEncoding() == BitCodeAbbrevOp::Array && + !Op.getEncoding() == BitCodeAbbrevOp::Blob && + "Expected literal or scalar code"); + + if (Op.isLiteral()) + EmitAbbreviatedLiteral(Op, Code.getValue()); + else + EmitAbbreviatedField(Op, Code.getValue()); + } + + // Main loop, emitting all value in Vals. + for (; i != e; ++i) { const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); if (Op.isLiteral()) { assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); @@ -396,10 +415,8 @@ return; } - // Insert the code into Vals to treat it uniformly. - Vals.insert(Vals.begin(), Code); - - EmitRecordWithAbbrev(Abbrev, makeArrayRef(Vals)); + EmitRecordWithAbbrevImpl(Abbrev, makeArrayRef(Vals), StringRef(), + Optional(Code)); } /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation.