summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp204
1 files changed, 109 insertions, 95 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index aa7a301687f..88883fdd448 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -15,7 +15,6 @@
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDumper.h"
@@ -222,8 +221,8 @@ TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) {
// Build the fully qualified name of the scope.
std::string ScopeName = getFullyQualifiedName(Scope);
- TypeIndex TI =
- TypeTable.writeKnownType(StringIdRecord(TypeIndex(), ScopeName));
+ StringIdRecord SID(TypeIndex(), ScopeName);
+ auto TI = TypeTable.writeKnownType(SID);
return recordTypeIndexForDINode(Scope, TI);
}
@@ -469,47 +468,47 @@ void CodeViewDebug::emitTypeInformation() {
}
CVTypeDumper CVTD(nullptr, /*PrintRecordBytes=*/false);
- TypeTable.ForEachRecord(
- [&](TypeIndex Index, StringRef Record) {
- if (OS.isVerboseAsm()) {
- // Emit a block comment describing the type record for readability.
- SmallString<512> CommentBlock;
- raw_svector_ostream CommentOS(CommentBlock);
- ScopedPrinter SP(CommentOS);
- SP.setPrefix(CommentPrefix);
- CVTD.setPrinter(&SP);
- Error E = CVTD.dump({Record.bytes_begin(), Record.bytes_end()});
- if (E) {
- logAllUnhandledErrors(std::move(E), errs(), "error: ");
- llvm_unreachable("produced malformed type record");
- }
- // emitRawComment will insert its own tab and comment string before
- // the first line, so strip off our first one. It also prints its own
- // newline.
- OS.emitRawComment(
- CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim());
- } else {
+ TypeTable.ForEachRecord([&](TypeIndex Index, ArrayRef<uint8_t> Record) {
+ if (OS.isVerboseAsm()) {
+ // Emit a block comment describing the type record for readability.
+ SmallString<512> CommentBlock;
+ raw_svector_ostream CommentOS(CommentBlock);
+ ScopedPrinter SP(CommentOS);
+ SP.setPrefix(CommentPrefix);
+ CVTD.setPrinter(&SP);
+ Error E = CVTD.dump(Record);
+ if (E) {
+ logAllUnhandledErrors(std::move(E), errs(), "error: ");
+ llvm_unreachable("produced malformed type record");
+ }
+ // emitRawComment will insert its own tab and comment string before
+ // the first line, so strip off our first one. It also prints its own
+ // newline.
+ OS.emitRawComment(
+ CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim());
+ } else {
#ifndef NDEBUG
- // Assert that the type data is valid even if we aren't dumping
- // comments. The MSVC linker doesn't do much type record validation,
- // so the first link of an invalid type record can succeed while
- // subsequent links will fail with LNK1285.
- ByteStream Stream({Record.bytes_begin(), Record.bytes_end()});
- CVTypeArray Types;
- StreamReader Reader(Stream);
- Error E = Reader.readArray(Types, Reader.getLength());
- if (!E) {
- TypeVisitorCallbacks C;
- E = CVTypeVisitor(C).visitTypeStream(Types);
- }
- if (E) {
- logAllUnhandledErrors(std::move(E), errs(), "error: ");
- llvm_unreachable("produced malformed type record");
- }
+ // Assert that the type data is valid even if we aren't dumping
+ // comments. The MSVC linker doesn't do much type record validation,
+ // so the first link of an invalid type record can succeed while
+ // subsequent links will fail with LNK1285.
+ ByteStream Stream(Record);
+ CVTypeArray Types;
+ StreamReader Reader(Stream);
+ Error E = Reader.readArray(Types, Reader.getLength());
+ if (!E) {
+ TypeVisitorCallbacks C;
+ E = CVTypeVisitor(C).visitTypeStream(Types);
+ }
+ if (E) {
+ logAllUnhandledErrors(std::move(E), errs(), "error: ");
+ llvm_unreachable("produced malformed type record");
+ }
#endif
- }
- OS.EmitBinaryData(Record);
- });
+ }
+ StringRef S(reinterpret_cast<const char *>(Record.data()), Record.size());
+ OS.EmitBinaryData(S);
+ });
}
namespace {
@@ -1195,8 +1194,8 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
(i == 0 && ElementSize == 0) ? Ty->getSizeInBits() / 8 : ElementSize;
StringRef Name = (i == 0) ? Ty->getName() : "";
- ElementTypeIndex = TypeTable.writeKnownType(
- ArrayRecord(ElementTypeIndex, IndexType, ArraySize, Name));
+ ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);
+ ElementTypeIndex = TypeTable.writeKnownType(AR);
}
(void)PartiallyIncomplete;
@@ -1421,7 +1420,8 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType().resolve();
}
TypeIndex ModifiedTI = getTypeIndex(BaseTy);
- return TypeTable.writeKnownType(ModifierRecord(ModifiedTI, Mods));
+ ModifierRecord MR(ModifiedTI, Mods);
+ return TypeTable.writeKnownType(MR);
}
TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {
@@ -1478,9 +1478,10 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,
// TODO: Need to use the correct values for:
// FunctionOptions
// ThisPointerAdjustment.
- TypeIndex TI = TypeTable.writeKnownType(MemberFunctionRecord(
- ReturnTypeIndex, ClassType, ThisTypeIndex, CC, FunctionOptions::None,
- ArgTypeIndices.size(), ArgListIndex, ThisAdjustment));
+ MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC,
+ FunctionOptions::None, ArgTypeIndices.size(),
+ ArgListIndex, ThisAdjustment);
+ TypeIndex TI = TypeTable.writeKnownType(MFR);
return TI;
}
@@ -1488,7 +1489,9 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,
TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) {
unsigned VSlotCount = Ty->getSizeInBits() / (8 * Asm->MAI->getPointerSize());
SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near);
- return TypeTable.writeKnownType(VFTableShapeRecord(Slots));
+
+ VFTableShapeRecord VFTSR(Slots);
+ return TypeTable.writeKnownType(VFTSR);
}
static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) {
@@ -1578,25 +1581,28 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
if (Ty->isForwardDecl()) {
CO |= ClassOptions::ForwardReference;
} else {
- FieldListRecordBuilder Fields;
+ FieldListRecordBuilder FLRB(TypeTable);
+
+ FLRB.begin();
for (const DINode *Element : Ty->getElements()) {
// We assume that the frontend provides all members in source declaration
// order, which is what MSVC does.
if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
- Fields.writeMemberType(EnumeratorRecord(
- MemberAccess::Public, APSInt::getUnsigned(Enumerator->getValue()),
- Enumerator->getName()));
+ EnumeratorRecord ER(MemberAccess::Public,
+ APSInt::getUnsigned(Enumerator->getValue()),
+ Enumerator->getName());
+ FLRB.writeMemberType(ER);
EnumeratorCount++;
}
}
- FTI = TypeTable.writeFieldList(Fields);
+ FTI = FLRB.end();
}
std::string FullName = getFullyQualifiedName(Ty);
- return TypeTable.writeKnownType(EnumRecord(EnumeratorCount, CO, FTI, FullName,
- Ty->getIdentifier(),
- getTypeIndex(Ty->getBaseType())));
+ EnumRecord ER(EnumeratorCount, CO, FTI, FullName, Ty->getIdentifier(),
+ getTypeIndex(Ty->getBaseType()));
+ return TypeTable.writeKnownType(ER);
}
//===----------------------------------------------------------------------===//
@@ -1695,9 +1701,9 @@ TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) {
ClassOptions CO =
ClassOptions::ForwardReference | getCommonClassOptions(Ty);
std::string FullName = getFullyQualifiedName(Ty);
- TypeIndex FwdDeclTI = TypeTable.writeKnownType(
- ClassRecord(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0,
- FullName, Ty->getIdentifier()));
+ ClassRecord CR(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0,
+ FullName, Ty->getIdentifier());
+ TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR);
if (!Ty->isForwardDecl())
DeferredCompleteTypes.push_back(Ty);
return FwdDeclTI;
@@ -1721,14 +1727,14 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {
uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
- TypeIndex ClassTI = TypeTable.writeKnownType(
- ClassRecord(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI,
- SizeInBytes, FullName, Ty->getIdentifier()));
+ ClassRecord CR(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI,
+ SizeInBytes, FullName, Ty->getIdentifier());
+ TypeIndex ClassTI = TypeTable.writeKnownType(CR);
- TypeTable.writeKnownType(UdtSourceLineRecord(
- ClassTI, TypeTable.writeKnownType(StringIdRecord(
- TypeIndex(0x0), getFullFilepath(Ty->getFile()))),
- Ty->getLine()));
+ StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(Ty->getFile()));
+ TypeIndex SIDI = TypeTable.writeKnownType(SIDR);
+ UdtSourceLineRecord USLR(ClassTI, SIDI, Ty->getLine());
+ TypeTable.writeKnownType(USLR);
addToUDTs(Ty, ClassTI);
@@ -1739,8 +1745,8 @@ TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) {
ClassOptions CO =
ClassOptions::ForwardReference | getCommonClassOptions(Ty);
std::string FullName = getFullyQualifiedName(Ty);
- TypeIndex FwdDeclTI = TypeTable.writeKnownType(
- UnionRecord(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier()));
+ UnionRecord UR(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier());
+ TypeIndex FwdDeclTI = TypeTable.writeKnownType(UR);
if (!Ty->isForwardDecl())
DeferredCompleteTypes.push_back(Ty);
return FwdDeclTI;
@@ -1760,13 +1766,14 @@ TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) {
uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
std::string FullName = getFullyQualifiedName(Ty);
- TypeIndex UnionTI = TypeTable.writeKnownType(UnionRecord(
- FieldCount, CO, FieldTI, SizeInBytes, FullName, Ty->getIdentifier()));
+ UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
+ Ty->getIdentifier());
+ TypeIndex UnionTI = TypeTable.writeKnownType(UR);
- TypeTable.writeKnownType(UdtSourceLineRecord(
- UnionTI, TypeTable.writeKnownType(StringIdRecord(
- TypeIndex(0x0), getFullFilepath(Ty->getFile()))),
- Ty->getLine()));
+ StringIdRecord SIR(TypeIndex(0x0), getFullFilepath(Ty->getFile()));
+ TypeIndex SIRI = TypeTable.writeKnownType(SIR);
+ UdtSourceLineRecord USLR(UnionTI, SIRI, Ty->getLine());
+ TypeTable.writeKnownType(USLR);
addToUDTs(Ty, UnionTI);
@@ -1781,7 +1788,8 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
// list record.
unsigned MemberCount = 0;
ClassInfo Info = collectClassInfo(Ty);
- FieldListRecordBuilder Fields;
+ FieldListRecordBuilder FLBR(TypeTable);
+ FLBR.begin();
// Create base classes.
for (const DIDerivedType *I : Info.Inheritance) {
@@ -1794,16 +1802,19 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
auto RecordKind = (I->getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase
? TypeRecordKind::IndirectVirtualBaseClass
: TypeRecordKind::VirtualBaseClass;
- Fields.writeMemberType(VirtualBaseClassRecord(
+ VirtualBaseClassRecord VBCR(
RecordKind, translateAccessFlags(Ty->getTag(), I->getFlags()),
getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
- VBTableIndex));
+ VBTableIndex);
+
+ FLBR.writeMemberType(VBCR);
} else {
assert(I->getOffsetInBits() % 8 == 0 &&
"bases must be on byte boundaries");
- Fields.writeMemberType(BaseClassRecord(
- translateAccessFlags(Ty->getTag(), I->getFlags()),
- getTypeIndex(I->getBaseType()), I->getOffsetInBits() / 8));
+ BaseClassRecord BCR(translateAccessFlags(Ty->getTag(), I->getFlags()),
+ getTypeIndex(I->getBaseType()),
+ I->getOffsetInBits() / 8);
+ FLBR.writeMemberType(BCR);
}
}
@@ -1816,8 +1827,8 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
translateAccessFlags(Ty->getTag(), Member->getFlags());
if (Member->isStaticMember()) {
- Fields.writeMemberType(
- StaticDataMemberRecord(Access, MemberBaseType, MemberName));
+ StaticDataMemberRecord SDMR(Access, MemberBaseType, MemberName);
+ FLBR.writeMemberType(SDMR);
MemberCount++;
continue;
}
@@ -1825,7 +1836,8 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
// Virtual function pointer member.
if ((Member->getFlags() & DINode::FlagArtificial) &&
Member->getName().startswith("_vptr$")) {
- Fields.writeMemberType(VFPtrRecord(getTypeIndex(Member->getBaseType())));
+ VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));
+ FLBR.writeMemberType(VFPR);
MemberCount++;
continue;
}
@@ -1840,12 +1852,14 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
MemberOffsetInBits = CI->getZExtValue() + MemberInfo.BaseOffset;
}
StartBitOffset -= MemberOffsetInBits;
- MemberBaseType = TypeTable.writeKnownType(BitFieldRecord(
- MemberBaseType, Member->getSizeInBits(), StartBitOffset));
+ BitFieldRecord BFR(MemberBaseType, Member->getSizeInBits(),
+ StartBitOffset);
+ MemberBaseType = TypeTable.writeKnownType(BFR);
}
uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
- Fields.writeMemberType(DataMemberRecord(Access, MemberBaseType,
- MemberOffsetInBytes, MemberName));
+ DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes,
+ MemberName);
+ FLBR.writeMemberType(DMR);
MemberCount++;
}
@@ -1870,23 +1884,23 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
}
assert(Methods.size() > 0 && "Empty methods map entry");
if (Methods.size() == 1)
- Fields.writeMemberType(Methods[0]);
+ FLBR.writeMemberType(Methods[0]);
else {
- TypeIndex MethodList =
- TypeTable.writeKnownType(MethodOverloadListRecord(Methods));
- Fields.writeMemberType(
- OverloadedMethodRecord(Methods.size(), MethodList, Name));
+ MethodOverloadListRecord MOLR(Methods);
+ TypeIndex MethodList = TypeTable.writeKnownType(MOLR);
+ OverloadedMethodRecord OMR(Methods.size(), MethodList, Name);
+ FLBR.writeMemberType(OMR);
}
}
// Create nested classes.
for (const DICompositeType *Nested : Info.NestedClasses) {
NestedTypeRecord R(getTypeIndex(DITypeRef(Nested)), Nested->getName());
- Fields.writeMemberType(R);
+ FLBR.writeMemberType(R);
MemberCount++;
}
- TypeIndex FieldTI = TypeTable.writeFieldList(Fields);
+ TypeIndex FieldTI = FLBR.end();
return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount,
!Info.NestedClasses.empty());
}
OpenPOWER on IntegriCloud