aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo/CodeView/TypeTableBuilder.cpp')
-rw-r--r--lib/DebugInfo/CodeView/TypeTableBuilder.cpp224
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);
}