diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Bitcode/BitstreamWriter.h | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/llvm/include/llvm/Bitcode/BitstreamWriter.h b/llvm/include/llvm/Bitcode/BitstreamWriter.h index 9f23023a141..648a06e202e 100644 --- a/llvm/include/llvm/Bitcode/BitstreamWriter.h +++ b/llvm/include/llvm/Bitcode/BitstreamWriter.h @@ -15,6 +15,7 @@ #ifndef LLVM_BITCODE_BITSTREAMWRITER_H #define LLVM_BITCODE_BITSTREAMWRITER_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitCodes.h" @@ -285,10 +286,12 @@ private: /// EmitRecordWithAbbrevImpl - This is the core implementation of the record /// 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. + /// known to exist at the end of the record. If Code is specified, then + /// it is the record code to emit before the Vals, which must not contain + /// the code. template<typename uintty> void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, - StringRef Blob) { + StringRef Blob, Optional<unsigned> Code) { const char *BlobData = Blob.data(); unsigned BlobLen = (unsigned) Blob.size(); unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV; @@ -297,9 +300,23 @@ private: EmitCode(Abbrev); + unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); + if (Code) { + assert(e && "Expected non-empty abbreviation"); + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i++); + + if (Op.isLiteral()) + EmitAbbreviatedLiteral(Op, Code.getValue()); + else { + assert(Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob && + "Expected literal or scalar"); + EmitAbbreviatedField(Op, Code.getValue()); + } + } + unsigned RecordIdx = 0; - for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); - i != e; ++i) { + for (; i != e; ++i) { const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); if (Op.isLiteral()) { assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); @@ -307,7 +324,7 @@ private: ++RecordIdx; } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) { // Array case. - assert(i+2 == e && "array op not second to last?"); + assert(i + 2 == e && "array op not second to last?"); const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); // If this record has blob data, emit it, otherwise we must have record @@ -395,10 +412,7 @@ public: return; } - // Insert the code into Vals to treat it uniformly. - Vals.insert(Vals.begin(), Code); - - EmitRecordWithAbbrev(Abbrev, Vals); + EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(), Code); } /// EmitRecordWithAbbrev - Emit a record with the specified abbreviation. @@ -406,7 +420,7 @@ public: /// the first entry. template<typename uintty> void EmitRecordWithAbbrev(unsigned Abbrev, SmallVectorImpl<uintty> &Vals) { - EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef()); + EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(), None); } /// EmitRecordWithBlob - Emit the specified record to the stream, using an @@ -417,12 +431,13 @@ public: template<typename uintty> void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, StringRef Blob) { - EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob); + EmitRecordWithAbbrevImpl(Abbrev, Vals, Blob, None); } template<typename uintty> void EmitRecordWithBlob(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, const char *BlobData, unsigned BlobLen) { - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen)); + return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(BlobData, BlobLen), + None); } /// EmitRecordWithArray - Just like EmitRecordWithBlob, works with records @@ -430,13 +445,13 @@ public: template<typename uintty> void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, StringRef Array) { - EmitRecordWithAbbrevImpl(Abbrev, Vals, Array); + EmitRecordWithAbbrevImpl(Abbrev, Vals, Array, None); } template<typename uintty> void EmitRecordWithArray(unsigned Abbrev, SmallVectorImpl<uintty> &Vals, const char *ArrayData, unsigned ArrayLen) { - return EmitRecordWithAbbrevImpl(Abbrev, Vals, StringRef(ArrayData, - ArrayLen)); + return EmitRecordWithAbbrevImpl(Abbrev, Vals, + StringRef(ArrayData, ArrayLen), None); } //===--------------------------------------------------------------------===// |