summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-11-08 22:24:53 +0000
committerZachary Turner <zturner@google.com>2016-11-08 22:24:53 +0000
commit4efa0a4201c5df01817895f476dfac71b3064acc (patch)
treecd4c78a2b08baa8a3285c30d5a061e4a6acdbee3 /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parentcb3c9f6c749c6ec76b328c2a405b79430868ef23 (diff)
downloadbcm5719-llvm-4efa0a4201c5df01817895f476dfac71b3064acc.tar.gz
bcm5719-llvm-4efa0a4201c5df01817895f476dfac71b3064acc.zip
[CodeView] Hook up CodeViewRecordIO to type serialization path.
Previously support had been added for using CodeViewRecordIO to read (deserialize) CodeView type records. This patch adds support for writing those same records. With this patch, reading and writing of CodeView type records finally uses a single codepath. Differential Revision: https://reviews.llvm.org/D26253 llvm-svn: 286304
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