diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 |
commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
tree | 4def12e759965de927d963ac65840d663ef9d1ea /lib/DebugInfo/CodeView/TypeTableBuilder.cpp | |
parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) |
Notes
Diffstat (limited to 'lib/DebugInfo/CodeView/TypeTableBuilder.cpp')
-rw-r--r-- | lib/DebugInfo/CodeView/TypeTableBuilder.cpp | 224 |
1 files changed, 155 insertions, 69 deletions
diff --git a/lib/DebugInfo/CodeView/TypeTableBuilder.cpp b/lib/DebugInfo/CodeView/TypeTableBuilder.cpp index 4af5dcaf7228..647538ee8ceb 100644 --- a/lib/DebugInfo/CodeView/TypeTableBuilder.cpp +++ b/lib/DebugInfo/CodeView/TypeTableBuilder.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h" #include "llvm/DebugInfo/CodeView/MethodListRecordBuilder.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" @@ -18,42 +17,21 @@ using namespace llvm; using namespace codeview; -namespace { - -const int PointerKindShift = 0; -const int PointerModeShift = 5; -const int PointerSizeShift = 13; - -const int ClassHfaKindShift = 11; -const int ClassWindowsRTClassKindShift = 14; - -void writePointerBase(TypeRecordBuilder &Builder, - const PointerRecordBase &Record) { - Builder.writeTypeIndex(Record.getReferentType()); - uint32_t flags = - static_cast<uint32_t>(Record.getOptions()) | - (Record.getSize() << PointerSizeShift) | - (static_cast<uint32_t>(Record.getMode()) << PointerModeShift) | - (static_cast<uint32_t>(Record.getPointerKind()) << PointerKindShift); - Builder.writeUInt32(flags); -} -} - TypeTableBuilder::TypeTableBuilder() {} TypeTableBuilder::~TypeTableBuilder() {} TypeIndex TypeTableBuilder::writeModifier(const ModifierRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::Modifier); + TypeRecordBuilder Builder(Record.getKind()); Builder.writeTypeIndex(Record.getModifiedType()); - Builder.writeUInt16(static_cast<uint16_t>(Record.getOptions())); + Builder.writeUInt16(static_cast<uint16_t>(Record.getModifiers())); return writeRecord(Builder); } TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::Procedure); + TypeRecordBuilder Builder(Record.getKind()); Builder.writeTypeIndex(Record.getReturnType()); Builder.writeUInt8(static_cast<uint8_t>(Record.getCallConv())); @@ -66,7 +44,7 @@ TypeIndex TypeTableBuilder::writeProcedure(const ProcedureRecord &Record) { TypeIndex TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::MemberFunction); + TypeRecordBuilder Builder(Record.getKind()); Builder.writeTypeIndex(Record.getReturnType()); Builder.writeTypeIndex(Record.getClassType()); @@ -80,12 +58,11 @@ TypeTableBuilder::writeMemberFunction(const MemberFunctionRecord &Record) { return writeRecord(Builder); } -TypeIndex -TypeTableBuilder::writeArgumentList(const ArgumentListRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::ArgumentList); +TypeIndex TypeTableBuilder::writeArgList(const ArgListRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); - Builder.writeUInt32(Record.getArgumentTypes().size()); - for (TypeIndex TI : Record.getArgumentTypes()) { + Builder.writeUInt32(Record.getIndices().size()); + for (TypeIndex TI : Record.getIndices()) { Builder.writeTypeIndex(TI); } @@ -93,27 +70,28 @@ TypeTableBuilder::writeArgumentList(const ArgumentListRecord &Record) { } TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::Pointer); - - writePointerBase(Builder, Record); - - return writeRecord(Builder); -} - -TypeIndex -TypeTableBuilder::writePointerToMember(const PointerToMemberRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::Pointer); + TypeRecordBuilder Builder(Record.getKind()); - writePointerBase(Builder, Record); + Builder.writeTypeIndex(Record.getReferentType()); + uint32_t flags = static_cast<uint32_t>(Record.getOptions()) | + (Record.getSize() << PointerRecord::PointerSizeShift) | + (static_cast<uint32_t>(Record.getMode()) + << PointerRecord::PointerModeShift) | + (static_cast<uint32_t>(Record.getPointerKind()) + << PointerRecord::PointerKindShift); + Builder.writeUInt32(flags); - Builder.writeTypeIndex(Record.getContainingType()); - Builder.writeUInt16(static_cast<uint16_t>(Record.getRepresentation())); + if (Record.isPointerToMember()) { + const MemberPointerInfo &M = Record.getMemberInfo(); + Builder.writeTypeIndex(M.getContainingType()); + Builder.writeUInt16(static_cast<uint16_t>(M.getRepresentation())); + } return writeRecord(Builder); } TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::Array); + TypeRecordBuilder Builder(Record.getKind()); Builder.writeTypeIndex(Record.getElementType()); Builder.writeTypeIndex(Record.getIndexType()); @@ -123,28 +101,23 @@ TypeIndex TypeTableBuilder::writeArray(const ArrayRecord &Record) { return writeRecord(Builder); } -TypeIndex TypeTableBuilder::writeAggregate(const AggregateRecord &Record) { - assert((Record.getKind() == TypeRecordKind::Structure) || +TypeIndex TypeTableBuilder::writeClass(const ClassRecord &Record) { + assert((Record.getKind() == TypeRecordKind::Struct) || (Record.getKind() == TypeRecordKind::Class) || - (Record.getKind() == TypeRecordKind::Union)); + (Record.getKind() == TypeRecordKind::Interface)); TypeRecordBuilder Builder(Record.getKind()); Builder.writeUInt16(Record.getMemberCount()); uint16_t Flags = static_cast<uint16_t>(Record.getOptions()) | - (static_cast<uint16_t>(Record.getHfa()) << ClassHfaKindShift) | + (static_cast<uint16_t>(Record.getHfa()) << ClassRecord::HfaKindShift) | (static_cast<uint16_t>(Record.getWinRTKind()) - << ClassWindowsRTClassKindShift); + << ClassRecord::WinRTKindShift); Builder.writeUInt16(Flags); Builder.writeTypeIndex(Record.getFieldList()); - if (Record.getKind() != TypeRecordKind::Union) { - Builder.writeTypeIndex(Record.getDerivationList()); - Builder.writeTypeIndex(Record.getVTableShape()); - } else { - assert(Record.getDerivationList() == TypeIndex()); - assert(Record.getVTableShape() == TypeIndex()); - } + Builder.writeTypeIndex(Record.getDerivationList()); + Builder.writeTypeIndex(Record.getVTableShape()); Builder.writeEncodedUnsignedInteger(Record.getSize()); Builder.writeNullTerminatedString(Record.getName()); if ((Record.getOptions() & ClassOptions::HasUniqueName) != @@ -155,8 +128,25 @@ TypeIndex TypeTableBuilder::writeAggregate(const AggregateRecord &Record) { return writeRecord(Builder); } +TypeIndex TypeTableBuilder::writeUnion(const UnionRecord &Record) { + TypeRecordBuilder Builder(TypeRecordKind::Union); + Builder.writeUInt16(Record.getMemberCount()); + uint16_t Flags = + static_cast<uint16_t>(Record.getOptions()) | + (static_cast<uint16_t>(Record.getHfa()) << ClassRecord::HfaKindShift); + Builder.writeUInt16(Flags); + Builder.writeTypeIndex(Record.getFieldList()); + Builder.writeEncodedUnsignedInteger(Record.getSize()); + Builder.writeNullTerminatedString(Record.getName()); + if ((Record.getOptions() & ClassOptions::HasUniqueName) != + ClassOptions::None) { + Builder.writeNullTerminatedString(Record.getUniqueName()); + } + return writeRecord(Builder); +} + TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::Enum); + TypeRecordBuilder Builder(Record.getKind()); Builder.writeUInt16(Record.getMemberCount()); Builder.writeUInt16(static_cast<uint16_t>(Record.getOptions())); @@ -172,7 +162,7 @@ TypeIndex TypeTableBuilder::writeEnum(const EnumRecord &Record) { } TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::BitField); + TypeRecordBuilder Builder(Record.getKind()); Builder.writeTypeIndex(Record.getType()); Builder.writeUInt8(Record.getBitSize()); @@ -181,11 +171,11 @@ TypeIndex TypeTableBuilder::writeBitField(const BitFieldRecord &Record) { return writeRecord(Builder); } -TypeIndex TypeTableBuilder::writeVirtualTableShape( - const VirtualTableShapeRecord &Record) { - TypeRecordBuilder Builder(TypeRecordKind::VirtualTableShape); +TypeIndex +TypeTableBuilder::writeVFTableShape(const VFTableShapeRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); - ArrayRef<VirtualTableSlotKind> Slots = Record.getSlots(); + ArrayRef<VFTableSlotKind> Slots = Record.getSlots(); Builder.writeUInt16(Slots.size()); for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) { @@ -199,19 +189,115 @@ TypeIndex TypeTableBuilder::writeVirtualTableShape( return writeRecord(Builder); } +TypeIndex +TypeTableBuilder::writeVFTable(const VFTableRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + Builder.writeTypeIndex(Record.getCompleteClass()); + Builder.writeTypeIndex(Record.getOverriddenVTable()); + Builder.writeUInt32(Record.getVFPtrOffset()); + + // Sum up the lengths of the null-terminated names. + size_t NamesLen = Record.getName().size() + 1; + for (StringRef MethodName : Record.getMethodNames()) + NamesLen += MethodName.size() + 1; + + Builder.writeUInt32(NamesLen); + Builder.writeNullTerminatedString(Record.getName()); + for (StringRef MethodName : Record.getMethodNames()) + Builder.writeNullTerminatedString(MethodName); + + return writeRecord(Builder); +} + +TypeIndex TypeTableBuilder::writeStringId(const StringIdRecord &Record) { + TypeRecordBuilder Builder(TypeRecordKind::StringId); + Builder.writeTypeIndex(Record.getId()); + Builder.writeNullTerminatedString(Record.getString()); + return writeRecord(Builder); +} + +TypeIndex +TypeTableBuilder::writeUdtSourceLine(const UdtSourceLineRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + Builder.writeTypeIndex(Record.getUDT()); + Builder.writeTypeIndex(Record.getSourceFile()); + Builder.writeUInt32(Record.getLineNumber()); + return writeRecord(Builder); +} + +TypeIndex +TypeTableBuilder::writeUdtModSourceLine(const UdtModSourceLineRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + Builder.writeTypeIndex(Record.getUDT()); + Builder.writeTypeIndex(Record.getSourceFile()); + Builder.writeUInt32(Record.getLineNumber()); + Builder.writeUInt16(Record.getModule()); + return writeRecord(Builder); +} + +TypeIndex TypeTableBuilder::writeFuncId(const FuncIdRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + Builder.writeTypeIndex(Record.getParentScope()); + Builder.writeTypeIndex(Record.getFunctionType()); + Builder.writeNullTerminatedString(Record.getName()); + return writeRecord(Builder); +} + +TypeIndex +TypeTableBuilder::writeMemberFuncId(const MemberFuncIdRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + Builder.writeTypeIndex(Record.getClassType()); + Builder.writeTypeIndex(Record.getFunctionType()); + Builder.writeNullTerminatedString(Record.getName()); + return writeRecord(Builder); +} + +TypeIndex +TypeTableBuilder::writeBuildInfo(const BuildInfoRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + assert(Record.getArgs().size() <= UINT16_MAX); + Builder.writeUInt16(Record.getArgs().size()); + for (TypeIndex Arg : Record.getArgs()) + Builder.writeTypeIndex(Arg); + return writeRecord(Builder); +} + TypeIndex TypeTableBuilder::writeRecord(TypeRecordBuilder &Builder) { return writeRecord(Builder.str()); } TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) { - // TODO: Split the list into multiple records if it's longer than 64KB, using - // a subrecord of TypeRecordKind::Index to chain the records together. - return writeRecord(FieldList.str()); + return FieldList.writeListRecord(*this); } -TypeIndex -TypeTableBuilder::writeMethodList(MethodListRecordBuilder &MethodList) { +TypeIndex TypeTableBuilder::writeMethodOverloadList( + const MethodOverloadListRecord &Record) { + TypeRecordBuilder Builder(Record.getKind()); + for (const OneMethodRecord &Method : Record.getMethods()) { + uint16_t Flags = static_cast<uint16_t>(Method.getAccess()); + Flags |= static_cast<uint16_t>(Method.getKind()) + << MemberAttributes::MethodKindShift; + Flags |= static_cast<uint16_t>(Method.getOptions()); + Builder.writeUInt16(Flags); + Builder.writeUInt16(0); // padding + Builder.writeTypeIndex(Method.getType()); + if (Method.isIntroducingVirtual()) { + assert(Method.getVFTableOffset() >= 0); + Builder.writeInt32(Method.getVFTableOffset()); + } else { + assert(Method.getVFTableOffset() == -1); + } + } + // TODO: Split the list into multiple records if it's longer than 64KB, using // a subrecord of TypeRecordKind::Index to chain the records together. - return writeRecord(MethodList.str()); + return writeRecord(Builder); +} + +TypeIndex TypeTableBuilder::writeTypeServer2(const TypeServer2Record &Record) { + TypeRecordBuilder Builder(Record.getKind()); + Builder.writeGuid(Record.getGuid()); + Builder.writeUInt32(Record.getAge()); + Builder.writeNullTerminatedString(Record.getName()); + return writeRecord(Builder); } |