1#include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h" 2 3using namespace llvm; 4using namespace llvm::codeview; 5 6static void addPadding(BinaryStreamWriter &Writer) { 7 uint32_t Align = Writer.getOffset() % 4; 8 if (Align == 0) 9 return; 10 11 int PaddingBytes = 4 - Align; 12 while (PaddingBytes > 0) { 13 uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes); 14 cantFail(Writer.writeInteger(Pad)); 15 --PaddingBytes; 16 } 17} 18 19SimpleTypeSerializer::SimpleTypeSerializer() : ScratchBuffer(MaxRecordLength) {} 20 21SimpleTypeSerializer::~SimpleTypeSerializer() {} 22 23template <typename T> 24ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) { 25 BinaryStreamWriter Writer(ScratchBuffer, support::little); 26 TypeRecordMapping Mapping(Writer); 27 28 // Write the record prefix first with a dummy length but real kind. 29 RecordPrefix DummyPrefix(uint16_t(Record.getKind())); 30 cantFail(Writer.writeObject(DummyPrefix)); 31 32 RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data()); 33 CVType CVT(Prefix, sizeof(RecordPrefix)); 34 35 cantFail(Mapping.visitTypeBegin(CVT)); 36 cantFail(Mapping.visitKnownRecord(CVT, Record)); 37 cantFail(Mapping.visitTypeEnd(CVT)); 38 39 addPadding(Writer); 40 41 // Update the size and kind after serialization. 42 Prefix->RecordKind = CVT.kind(); 43 Prefix->RecordLen = Writer.getOffset() - sizeof(uint16_t); 44 45 return {ScratchBuffer.data(), Writer.getOffset()}; 46} 47 48// Explicitly instantiate the member function for each known type so that we can 49// implement this in the cpp file. 50#define TYPE_RECORD(EnumName, EnumVal, Name) \ 51 template ArrayRef<uint8_t> llvm::codeview::SimpleTypeSerializer::serialize( \ 52 Name##Record &Record); 53#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 54#define MEMBER_RECORD(EnumName, EnumVal, Name) 55#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 56#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" 57