diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 204 |
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()); } |