1 //===-- TypeRecordBuilder.cpp ---------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/CodeView/TypeRecordBuilder.h" 11 12 using namespace llvm; 13 using namespace codeview; 14 TypeRecordBuilder(TypeRecordKind Kind)15TypeRecordBuilder::TypeRecordBuilder(TypeRecordKind Kind) 16 : Stream(Buffer), Writer(Stream) { 17 writeTypeRecordKind(Kind); 18 } 19 str()20StringRef TypeRecordBuilder::str() { 21 return StringRef(Buffer.data(), Buffer.size()); 22 } 23 writeUInt8(uint8_t Value)24void TypeRecordBuilder::writeUInt8(uint8_t Value) { 25 Writer.write(Value); 26 } 27 writeInt16(int16_t Value)28void TypeRecordBuilder::writeInt16(int16_t Value) { 29 Writer.write(Value); 30 } 31 writeUInt16(uint16_t Value)32void TypeRecordBuilder::writeUInt16(uint16_t Value) { 33 Writer.write(Value); 34 } 35 writeInt32(int32_t Value)36void TypeRecordBuilder::writeInt32(int32_t Value) { 37 Writer.write(Value); 38 } 39 writeUInt32(uint32_t Value)40void TypeRecordBuilder::writeUInt32(uint32_t Value) { 41 Writer.write(Value); 42 } 43 writeInt64(int64_t Value)44void TypeRecordBuilder::writeInt64(int64_t Value) { 45 Writer.write(Value); 46 } 47 writeUInt64(uint64_t Value)48void TypeRecordBuilder::writeUInt64(uint64_t Value) { 49 Writer.write(Value); 50 } 51 writeEncodedInteger(int64_t Value)52void TypeRecordBuilder::writeEncodedInteger(int64_t Value) { 53 if (Value >= 0) { 54 writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)); 55 } else { 56 writeEncodedSignedInteger(Value); 57 } 58 } 59 writeEncodedSignedInteger(int64_t Value)60void TypeRecordBuilder::writeEncodedSignedInteger(int64_t Value) { 61 if (Value >= std::numeric_limits<int8_t>::min() && 62 Value <= std::numeric_limits<int8_t>::max()) { 63 writeUInt16(LF_CHAR); 64 writeInt16(static_cast<int8_t>(Value)); 65 } else if (Value >= std::numeric_limits<int16_t>::min() && 66 Value <= std::numeric_limits<int16_t>::max()) { 67 writeUInt16(LF_SHORT); 68 writeInt16(static_cast<int16_t>(Value)); 69 } else if (Value >= std::numeric_limits<int32_t>::min() && 70 Value <= std::numeric_limits<int32_t>::max()) { 71 writeUInt16(LF_LONG); 72 writeInt32(static_cast<int32_t>(Value)); 73 } else { 74 writeUInt16(LF_QUADWORD); 75 writeInt64(Value); 76 } 77 } 78 writeEncodedUnsignedInteger(uint64_t Value)79void TypeRecordBuilder::writeEncodedUnsignedInteger(uint64_t Value) { 80 if (Value < LF_CHAR) { 81 writeUInt16(static_cast<uint16_t>(Value)); 82 } else if (Value <= std::numeric_limits<uint16_t>::max()) { 83 writeUInt16(LF_USHORT); 84 writeUInt16(static_cast<uint16_t>(Value)); 85 } else if (Value <= std::numeric_limits<uint32_t>::max()) { 86 writeUInt16(LF_ULONG); 87 writeUInt32(static_cast<uint32_t>(Value)); 88 } else { 89 writeUInt16(LF_UQUADWORD); 90 writeUInt64(Value); 91 } 92 } 93 writeNullTerminatedString(StringRef Value)94void TypeRecordBuilder::writeNullTerminatedString(StringRef Value) { 95 // Microsoft's linker seems to have trouble with symbol names longer than 96 // 0xffd8 bytes. 97 Value = Value.substr(0, 0xffd8); 98 Stream.write(Value.data(), Value.size()); 99 writeUInt8(0); 100 } 101 writeGuid(StringRef Guid)102void TypeRecordBuilder::writeGuid(StringRef Guid) { 103 assert(Guid.size() == 16); 104 Stream.write(Guid.data(), 16); 105 } 106 writeTypeIndex(TypeIndex TypeInd)107void TypeRecordBuilder::writeTypeIndex(TypeIndex TypeInd) { 108 writeUInt32(TypeInd.getIndex()); 109 } 110 writeTypeRecordKind(TypeRecordKind Kind)111void TypeRecordBuilder::writeTypeRecordKind(TypeRecordKind Kind) { 112 writeUInt16(static_cast<uint16_t>(Kind)); 113 } 114