diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h new file mode 100644 index 00000000000..773cfa22bc7 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h @@ -0,0 +1,135 @@ +//===- CodeViewRecordIO.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H +#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H + +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/DebugInfo/MSF/StreamWriter.h" +#include "llvm/Support/Error.h" + +#include +#include + +namespace llvm { +namespace msf { +class StreamReader; +class StreamWriter; +} +namespace codeview { + +class CodeViewRecordIO { + struct ActiveRecord { + uint16_t Kind; + }; + +public: + explicit CodeViewRecordIO(msf::StreamReader &Reader) : Reader(&Reader) {} + explicit CodeViewRecordIO(msf::StreamWriter &Writer) : Writer(&Writer) {} + + Error beginRecord(uint16_t Kind); + Error endRecord(); + Error mapInteger(TypeIndex &TypeInd); + + bool isReading() const { return Reader != nullptr; } + bool isWriting() const { return !isReading(); } + + template Error mapInteger(T &Value) { + if (isWriting()) + return Writer->writeInteger(Value); + + return Reader->readInteger(Value); + } + + template Error mapEnum(T &Value) { + using U = typename std::underlying_type::type; + U X; + if (isWriting()) + X = static_cast(Value); + + if (auto EC = mapInteger(X)) + return EC; + if (isReading()) + Value = static_cast(X); + return Error::success(); + } + + Error mapEncodedInteger(int64_t &Value); + Error mapEncodedInteger(uint64_t &Value); + Error mapEncodedInteger(APSInt &Value); + Error mapStringZ(StringRef &Value); + Error mapGuid(StringRef &Guid); + + template + Error mapVectorN(T &Items, const ElementMapper &Mapper) { + SizeType Size; + if (isWriting()) { + Size = static_cast(Items.size()); + if (auto EC = Writer->writeInteger(Size)) + return EC; + + for (auto &X : Items) { + if (auto EC = Mapper(*this, X)) + return EC; + } + } else { + if (auto EC = Reader->readInteger(Size)) + return EC; + for (SizeType I = 0; I < Size; ++I) { + typename T::value_type Item; + if (auto EC = Mapper(*this, Item)) + return EC; + Items.push_back(Item); + } + } + + return Error::success(); + } + + template + Error mapVectorTail(T &Items, const ElementMapper &Mapper) { + if (isWriting()) { + for (auto &Item : Items) { + if (auto EC = Mapper(*this, Item)) + return EC; + } + } else { + typename T::value_type Field; + // Stop when we run out of bytes or we hit record padding bytes. + while (!Reader->empty() && Reader->peek() < LF_PAD0) { + if (auto EC = Mapper(*this, Field)) + return EC; + Items.push_back(Field); + } + } + return Error::success(); + } + + Error mapByteVectorTail(ArrayRef &Bytes); + + Error skipPadding(); + +private: + Error writeEncodedSignedInteger(const int64_t &Value); + Error writeEncodedUnsignedInteger(const uint64_t &Value); + + Optional CurrentRecord; + + msf::StreamReader *Reader = nullptr; + msf::StreamWriter *Writer = nullptr; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h index 232c9033617..b42d6951cb8 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h @@ -10,57 +10,108 @@ #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H #define LLVM_DEBUGINFO_CODEVIEW_TYPEDESERIALIZER_H +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" +#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" #include "llvm/DebugInfo/MSF/ByteStream.h" #include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/DebugInfo/MSF/StreamWriter.h" #include "llvm/Support/Error.h" namespace llvm { namespace codeview { + class TypeDeserializer : public TypeVisitorCallbacks { + struct MappingInfo { + explicit MappingInfo(ArrayRef RecordData) + : Stream(RecordData), Reader(Stream), Mapping(Reader) {} + + msf::ByteStream Stream; + msf::StreamReader Reader; + TypeRecordMapping Mapping; + }; + public: TypeDeserializer() {} + Error visitTypeBegin(CVType &Record) override { + assert(!Mapping && "Already in a type mapping!"); + Mapping = llvm::make_unique(Record.content()); + return Mapping->Mapping.visitTypeBegin(Record); + } + Error visitTypeEnd(CVType &Record) override { + assert(Mapping && "Not in a type mapping!"); + auto EC = Mapping->Mapping.visitTypeEnd(Record); + Mapping.reset(); + return EC; + } + #define TYPE_RECORD(EnumName, EnumVal, Name) \ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \ - return defaultVisitKnownRecord(CVR, Record); \ + return visitKnownRecordImpl(CVR, Record); \ } +#define MEMBER_RECORD(EnumName, EnumVal, Name) +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "TypeRecords.def" + +private: + template + Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) { + return Mapping->Mapping.visitKnownRecord(CVR, Record); + } + + std::unique_ptr Mapping; +}; + +class FieldListDeserializer : public TypeVisitorCallbacks { + struct MappingInfo { + explicit MappingInfo(msf::StreamReader &R) + : Reader(R), Mapping(Reader), StartOffset(0) {} + + msf::StreamReader &Reader; + TypeRecordMapping Mapping; + uint32_t StartOffset; + }; + +public: + explicit FieldListDeserializer(msf::StreamReader &Reader) : Mapping(Reader) {} + + Error visitMemberBegin(CVMemberRecord &Record) override { + Mapping.StartOffset = Mapping.Reader.getOffset(); + return Mapping.Mapping.visitMemberBegin(Record); + } + Error visitMemberEnd(CVMemberRecord &Record) override { + if (auto EC = Mapping.Mapping.visitMemberEnd(Record)) + return EC; + return Error::success(); + } + +#define TYPE_RECORD(EnumName, EnumVal, Name) #define MEMBER_RECORD(EnumName, EnumVal, Name) \ Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \ - return defaultVisitKnownMember(CVR, Record); \ + return visitKnownMemberImpl(CVR, Record); \ } #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) #include "TypeRecords.def" -protected: - template - Error deserializeRecord(msf::StreamReader &Reader, TypeLeafKind Kind, - T &Record) const { - TypeRecordKind RK = static_cast(Kind); - auto ExpectedRecord = T::deserialize(RK, Reader); - if (!ExpectedRecord) - return ExpectedRecord.takeError(); - Record = std::move(*ExpectedRecord); - return Error::success(); - } - private: - template Error defaultVisitKnownRecord(CVType &CVR, T &Record) { - msf::ByteStream S(CVR.content()); - msf::StreamReader SR(S); - if (auto EC = deserializeRecord(SR, CVR.Type, Record)) - return EC; - return Error::success(); - } - template - Error defaultVisitKnownMember(CVMemberRecord &CVMR, T &Record) { - msf::ByteStream S(CVMR.Data); - msf::StreamReader SR(S); - if (auto EC = deserializeRecord(SR, CVMR.Kind, Record)) + template + Error visitKnownMemberImpl(CVMemberRecord &CVR, RecordType &Record) { + if (auto EC = Mapping.Mapping.visitKnownMember(CVR, Record)) return EC; + + uint32_t EndOffset = Mapping.Reader.getOffset(); + uint32_t RecordLength = EndOffset - Mapping.StartOffset; + Mapping.Reader.setOffset(Mapping.StartOffset); + if (auto EC = Mapping.Reader.readBytes(CVR.Data, RecordLength)) + return EC; + assert(Mapping.Reader.getOffset() == EndOffset); return Error::success(); } + MappingInfo Mapping; }; } } diff --git a/include/llvm/DebugInfo/CodeView/TypeIndex.h b/include/llvm/DebugInfo/CodeView/TypeIndex.h index c2ebf384889..29e3369f9e4 100644 --- a/include/llvm/DebugInfo/CodeView/TypeIndex.h +++ b/include/llvm/DebugInfo/CodeView/TypeIndex.h @@ -101,6 +101,7 @@ public: : Index(static_cast(Kind) | static_cast(Mode)) {} uint32_t getIndex() const { return Index; } + void setIndex(uint32_t I) { Index = I; } bool isSimple() const { return Index < FirstNonSimpleIndex; } bool isNoneType() const { return *this == None(); } diff --git a/include/llvm/DebugInfo/CodeView/TypeRecord.h b/include/llvm/DebugInfo/CodeView/TypeRecord.h index 2f093f5caf6..7b8a3f35a38 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -43,10 +43,20 @@ typedef msf::VarStreamArray CVTypeArray; /// Equvalent to CV_fldattr_t in cvinfo.h. struct MemberAttributes { - ulittle16_t Attrs; + uint16_t Attrs; enum { MethodKindShift = 2, }; + MemberAttributes() : Attrs(0) {} + + explicit MemberAttributes(MemberAccess Access) + : Attrs(static_cast(Access)) {} + + MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) { + Attrs = static_cast(Access); + Attrs |= (static_cast(Kind) << MethodKindShift); + Attrs |= static_cast(Flags); + } /// Get the access specifier. Valid for any kind of member. MemberAccess getAccess() const { @@ -97,8 +107,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(msf::StreamReader &Reader); - TypeIndex getContainingType() const { return ContainingType; } PointerToMemberRepresentation getRepresentation() const { return Representation; @@ -106,12 +114,6 @@ public: TypeIndex ContainingType; PointerToMemberRepresentation Representation; - -private: - struct Layout { - TypeIndex ClassType; - ulittle16_t Representation; // PointerToMemberRepresentation - }; }; class TypeRecord { @@ -138,20 +140,11 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getModifiedType() const { return ModifiedType; } ModifierOptions getModifiers() const { return Modifiers; } TypeIndex ModifiedType; ModifierOptions Modifiers; - -private: - struct Layout { - TypeIndex ModifiedType; - ulittle16_t Modifiers; // ModifierOptions - }; }; // LF_PROCEDURE @@ -169,11 +162,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - - static uint32_t getLayoutSize() { return 2 + sizeof(Layout); } - TypeIndex getReturnType() const { return ReturnType; } CallingConvention getCallConv() const { return CallConv; } FunctionOptions getOptions() const { return Options; } @@ -185,15 +173,6 @@ public: FunctionOptions Options; uint16_t ParameterCount; TypeIndex ArgumentList; - -private: - struct Layout { - TypeIndex ReturnType; - CallingConvention CallConv; - FunctionOptions Options; - ulittle16_t NumParameters; - TypeIndex ArgListType; - }; }; // LF_MFUNCTION @@ -215,9 +194,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getReturnType() const { return ReturnType; } TypeIndex getClassType() const { return ClassType; } TypeIndex getThisType() const { return ThisType; } @@ -235,18 +211,6 @@ public: uint16_t ParameterCount; TypeIndex ArgumentList; int32_t ThisPointerAdjustment; - -private: - struct Layout { - TypeIndex ReturnType; - TypeIndex ClassType; - TypeIndex ThisType; - CallingConvention CallConv; - FunctionOptions Options; - ulittle16_t NumParameters; - TypeIndex ArgListType; - little32_t ThisAdjustment; - }; }; // LF_MFUNC_ID @@ -262,21 +226,12 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); TypeIndex getClassType() const { return ClassType; } TypeIndex getFunctionType() const { return FunctionType; } StringRef getName() const { return Name; } TypeIndex ClassType; TypeIndex FunctionType; StringRef Name; - -private: - struct Layout { - TypeIndex ClassType; - TypeIndex FunctionType; - // Name: The null-terminated name follows. - }; }; // LF_ARGLIST, LF_SUBSTR_LIST @@ -291,20 +246,9 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - ArrayRef getIndices() const { return StringIndices; } - static uint32_t getLayoutSize() { return 2 + sizeof(Layout); } - std::vector StringIndices; - -private: - struct Layout { - ulittle32_t NumArgs; // Number of arguments - // ArgTypes[]: Type indicies of arguments - }; }; // LF_POINTER @@ -316,91 +260,82 @@ public: static const uint32_t PointerModeShift = 5; static const uint32_t PointerModeMask = 0x07; + static const uint32_t PointerOptionMask = 0xFF; + static const uint32_t PointerSizeShift = 13; static const uint32_t PointerSizeMask = 0xFF; explicit PointerRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} - PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode, - PointerOptions Options, uint8_t Size) + PointerRecord(TypeIndex ReferentType, uint32_t Attrs) : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), - PtrKind(Kind), Mode(Mode), Options(Options), Size(Size) {} + Attrs(Attrs) {} - PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode, - PointerOptions Options, uint8_t Size, + PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM, + PointerOptions PO, uint8_t Size) + : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), + Attrs(calcAttrs(PK, PM, PO, Size)) {} + + PointerRecord(TypeIndex ReferentType, PointerKind PK, PointerMode PM, + PointerOptions PO, uint8_t Size, const MemberPointerInfo &Member) : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), - PtrKind(Kind), Mode(Mode), Options(Options), Size(Size), - MemberInfo(Member) {} + Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(Member) {} + + PointerRecord(TypeIndex ReferentType, uint32_t Attrs, + const MemberPointerInfo &Member) + : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), + Attrs(Attrs), MemberInfo(Member) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getReferentType() const { return ReferentType; } - PointerKind getPointerKind() const { return PtrKind; } - PointerMode getMode() const { return Mode; } - PointerOptions getOptions() const { return Options; } - uint8_t getSize() const { return Size; } + PointerKind getPointerKind() const { + return static_cast((Attrs >> PointerKindShift) & + PointerKindMask); + } + PointerMode getMode() const { + return static_cast((Attrs >> PointerModeShift) & + PointerModeMask); + } + PointerOptions getOptions() const { + return static_cast(Attrs); + } + uint8_t getSize() const { + return (Attrs >> PointerSizeShift) & PointerSizeMask; + } MemberPointerInfo getMemberInfo() const { return *MemberInfo; } bool isPointerToMember() const { - return Mode == PointerMode::PointerToDataMember || - Mode == PointerMode::PointerToMemberFunction; - } - bool isFlat() const { - return !!(uint32_t(Options) & uint32_t(PointerOptions::Flat32)); - } - bool isConst() const { - return !!(uint32_t(Options) & uint32_t(PointerOptions::Const)); + return getMode() == PointerMode::PointerToDataMember || + getMode() == PointerMode::PointerToMemberFunction; } + bool isFlat() const { return !!(Attrs & uint32_t(PointerOptions::Flat32)); } + bool isConst() const { return !!(Attrs & uint32_t(PointerOptions::Const)); } bool isVolatile() const { - return !!(uint32_t(Options) & uint32_t(PointerOptions::Volatile)); + return !!(Attrs & uint32_t(PointerOptions::Volatile)); } bool isUnaligned() const { - return !!(uint32_t(Options) & uint32_t(PointerOptions::Unaligned)); + return !!(Attrs & uint32_t(PointerOptions::Unaligned)); } TypeIndex ReferentType; - PointerKind PtrKind; - PointerMode Mode; - PointerOptions Options; - uint8_t Size; + uint32_t Attrs; + Optional MemberInfo; private: - struct Layout { - TypeIndex PointeeType; - ulittle32_t Attrs; // pointer attributes - // if pointer to member: - // PointerToMemberTail - PointerKind getPtrKind() const { - return PointerKind(Attrs & PointerKindMask); - } - PointerMode getPtrMode() const { - return PointerMode((Attrs >> PointerModeShift) & PointerModeMask); - } - uint8_t getPtrSize() const { - return (Attrs >> PointerSizeShift) & PointerSizeMask; - } - bool isFlat() const { return Attrs & (1 << 8); } - bool isVolatile() const { return Attrs & (1 << 9); } - bool isConst() const { return Attrs & (1 << 10); } - bool isUnaligned() const { return Attrs & (1 << 11); } - - bool isPointerToDataMember() const { - return getPtrMode() == PointerMode::PointerToDataMember; - } - bool isPointerToMemberFunction() const { - return getPtrMode() == PointerMode::PointerToMemberFunction; - } - bool isPointerToMember() const { - return isPointerToMemberFunction() || isPointerToDataMember(); - } - }; + static uint32_t calcAttrs(PointerKind PK, PointerMode PM, PointerOptions PO, + uint8_t Size) { + uint32_t A = 0; + A |= static_cast(PK); + A |= static_cast(PO); + A |= (static_cast(PM) << PointerModeShift); + A |= (static_cast(Size) << PointerSizeShift); + return A; + } }; // LF_NESTTYPE @@ -414,21 +349,11 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getNestedType() const { return Type; } StringRef getName() const { return Name; } TypeIndex Type; StringRef Name; - -private: - struct Layout { - ulittle16_t Pad0; // Should be zero - TypeIndex Type; // Type index of nested type - // Name: Null-terminated string - }; }; // LF_FIELDLIST @@ -442,9 +367,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap) { return false; } - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - ArrayRef Data; }; @@ -461,9 +383,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getElementType() const { return ElementType; } TypeIndex getIndexType() const { return IndexType; } uint64_t getSize() const { return Size; } @@ -473,14 +392,6 @@ public: TypeIndex IndexType; uint64_t Size; llvm::StringRef Name; - -private: - struct Layout { - TypeIndex ElementType; - TypeIndex IndexType; - // SizeOf: LF_NUMERIC encoded size in bytes. Not element count! - // Name: The null-terminated name follows. - }; }; class TagRecord : public TypeRecord { @@ -501,6 +412,10 @@ public: static const int WinRTKindShift = 14; static const int WinRTKindMask = 0xC000; + bool hasUniqueName() const { + return (Options & ClassOptions::HasUniqueName) != ClassOptions::None; + } + uint16_t getMemberCount() const { return MemberCount; } ClassOptions getOptions() const { return Options; } TypeIndex getFieldList() const { return FieldList; } @@ -519,81 +434,52 @@ class ClassRecord : public TagRecord { public: explicit ClassRecord(TypeRecordKind Kind) : TagRecord(Kind) {} ClassRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options, - HfaKind Hfa, WindowsRTClassKind WinRTKind, TypeIndex FieldList, - TypeIndex DerivationList, TypeIndex VTableShape, uint64_t Size, - StringRef Name, StringRef UniqueName) + TypeIndex FieldList, TypeIndex DerivationList, + TypeIndex VTableShape, uint64_t Size, StringRef Name, + StringRef UniqueName) : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName), - Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList), - VTableShape(VTableShape), Size(Size) {} + DerivationList(DerivationList), VTableShape(VTableShape), Size(Size) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - - HfaKind getHfa() const { return Hfa; } - WindowsRTClassKind getWinRTKind() const { return WinRTKind; } + HfaKind getHfa() const { + uint16_t Value = static_cast(Options); + Value = (Value & HfaKindMask) >> HfaKindShift; + return static_cast(Value); + } + WindowsRTClassKind getWinRTKind() const { + uint16_t Value = static_cast(Options); + Value = (Value & WinRTKindMask) >> WinRTKindShift; + return static_cast(Value); + } TypeIndex getDerivationList() const { return DerivationList; } TypeIndex getVTableShape() const { return VTableShape; } uint64_t getSize() const { return Size; } - HfaKind Hfa; - WindowsRTClassKind WinRTKind; TypeIndex DerivationList; TypeIndex VTableShape; uint64_t Size; - -private: - struct Layout { - ulittle16_t MemberCount; // Number of members in FieldList. - ulittle16_t Properties; // ClassOptions bitset - TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members - TypeIndex DerivedFrom; // LF_DERIVED: List of known derived classes - TypeIndex VShape; // LF_VTSHAPE: Shape of the vftable - // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC - // integer. - // Name: The null-terminated name follows. - - bool hasUniqueName() const { - return Properties & uint16_t(ClassOptions::HasUniqueName); - } - }; }; // LF_UNION struct UnionRecord : public TagRecord { explicit UnionRecord(TypeRecordKind Kind) : TagRecord(Kind) {} - UnionRecord(uint16_t MemberCount, ClassOptions Options, HfaKind Hfa, - TypeIndex FieldList, uint64_t Size, StringRef Name, - StringRef UniqueName) + UnionRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, + uint64_t Size, StringRef Name, StringRef UniqueName) : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name, UniqueName), - Hfa(Hfa), Size(Size) {} + Size(Size) {} - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - - HfaKind getHfa() const { return Hfa; } + HfaKind getHfa() const { + uint16_t Value = static_cast(Options); + Value = (Value & HfaKindMask) >> HfaKindShift; + return static_cast(Value); + } uint64_t getSize() const { return Size; } - HfaKind Hfa; uint64_t Size; - -private: - struct Layout { - ulittle16_t MemberCount; // Number of members in FieldList. - ulittle16_t Properties; // ClassOptions bitset - TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members - // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC - // integer. - // Name: The null-terminated name follows. - - bool hasUniqueName() const { - return Properties & uint16_t(ClassOptions::HasUniqueName); - } - }; }; // LF_ENUM @@ -609,25 +495,8 @@ public: /// Rewrite member type indices with IndexMap. Returns false if a type index is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getUnderlyingType() const { return UnderlyingType; } TypeIndex UnderlyingType; - -private: - struct Layout { - ulittle16_t NumEnumerators; // Number of enumerators - ulittle16_t Properties; - TypeIndex UnderlyingType; - TypeIndex FieldListType; - // Name: The null-terminated name follows. - - bool hasUniqueName() const { - return Properties & uint16_t(ClassOptions::HasUniqueName); - } - }; - }; // LF_BITFIELD @@ -642,23 +511,12 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getType() const { return Type; } uint8_t getBitOffset() const { return BitOffset; } uint8_t getBitSize() const { return BitSize; } TypeIndex Type; uint8_t BitSize; uint8_t BitOffset; - -private: - struct Layout { - TypeIndex Type; - uint8_t BitSize; - uint8_t BitOffset; - }; - }; // LF_VTSHAPE @@ -674,9 +532,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - ArrayRef getSlots() const { if (!SlotsRef.empty()) return SlotsRef; @@ -685,16 +540,6 @@ public: uint32_t getEntryCount() const { return getSlots().size(); } ArrayRef SlotsRef; std::vector Slots; - -private: - struct Layout { - // Number of vftable entries. Each method may have more than one entry due - // to - // things like covariant return types. - ulittle16_t VFEntryCount; - // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e. - }; - }; // LF_TYPESERVER2 @@ -709,9 +554,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - StringRef getGuid() const { return Guid; } uint32_t getAge() const { return Age; } @@ -720,13 +562,6 @@ public: StringRef Guid; uint32_t Age; StringRef Name; - -private: - struct Layout { - char Guid[16]; // GUID - ulittle32_t Age; - // Name: Name of the PDB as a null-terminated string - }; }; // LF_STRING_ID @@ -740,20 +575,11 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getId() const { return Id; } StringRef getString() const { return String; } TypeIndex Id; StringRef String; - -private: - struct Layout { - TypeIndex id; - // Name: Name of the PDB as a null-terminated string - }; }; // LF_FUNC_ID @@ -768,9 +594,6 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getParentScope() const { return ParentScope; } TypeIndex getFunctionType() const { return FunctionType; } @@ -779,14 +602,6 @@ public: TypeIndex ParentScope; TypeIndex FunctionType; StringRef Name; - -private: - struct Layout { - TypeIndex ParentScope; - TypeIndex FunctionType; - // Name: The null-terminated name follows. - }; - }; // LF_UDT_SRC_LINE @@ -801,23 +616,12 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } uint32_t getLineNumber() const { return LineNumber; } TypeIndex UDT; TypeIndex SourceFile; uint32_t LineNumber; - -private: - struct Layout { - TypeIndex UDT; // The user-defined type - TypeIndex SourceFile; // StringID containing the source filename - ulittle32_t LineNumber; - }; - }; // LF_UDT_MOD_SRC_LINE @@ -831,15 +635,6 @@ public: bool remapTypeIndices(ArrayRef IndexMap); - static Expected - deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - CV_DESERIALIZE(Reader, L); - - return UdtModSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber, - L->Module); - } - TypeIndex getUDT() const { return UDT; } TypeIndex getSourceFile() const { return SourceFile; } uint32_t getLineNumber() const { return LineNumber; } @@ -848,15 +643,6 @@ public: TypeIndex SourceFile; uint32_t LineNumber; uint16_t Module; - -private: - struct Layout { - TypeIndex UDT; // The user-defined type - TypeIndex SourceFile; // StringID containing the source filename - ulittle32_t LineNumber; - ulittle16_t Module; // Module that contributes this UDT definition - }; - }; // LF_BUILDINFO @@ -871,17 +657,8 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - ArrayRef getArgs() const { return ArgIndices; } SmallVector ArgIndices; - -private: - struct Layout { - ulittle16_t NumArgs; // Number of arguments - // ArgTypes[]: Type indicies of arguments - }; }; // LF_VFTABLE @@ -891,49 +668,28 @@ public: VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable, uint32_t VFPtrOffset, StringRef Name, ArrayRef Methods) - : TypeRecord(TypeRecordKind::VFTable), - CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable), - VFPtrOffset(VFPtrOffset), Name(Name), MethodNamesRef(Methods) {} - VFTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable, - uint32_t VFPtrOffset, StringRef Name, - const std::vector &Methods) - : TypeRecord(TypeRecordKind::VFTable), - CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable), - VFPtrOffset(VFPtrOffset), Name(Name), MethodNames(Methods) {} + : TypeRecord(TypeRecordKind::VFTable), CompleteClass(CompleteClass), + OverriddenVFTable(OverriddenVFTable), VFPtrOffset(VFPtrOffset) { + MethodNames.push_back(Name); + MethodNames.insert(MethodNames.end(), Methods.begin(), Methods.end()); + } /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getCompleteClass() const { return CompleteClass; } TypeIndex getOverriddenVTable() const { return OverriddenVFTable; } uint32_t getVFPtrOffset() const { return VFPtrOffset; } - StringRef getName() const { return Name; } + StringRef getName() const { return makeArrayRef(MethodNames).front(); } ArrayRef getMethodNames() const { - if (!MethodNamesRef.empty()) - return MethodNamesRef; - return MethodNames; + return makeArrayRef(MethodNames).drop_front(); } + TypeIndex CompleteClass; TypeIndex OverriddenVFTable; - ulittle32_t VFPtrOffset; - StringRef Name; - ArrayRef MethodNamesRef; + uint32_t VFPtrOffset; std::vector MethodNames; - -private: - struct Layout { - TypeIndex CompleteClass; // Class that owns this vftable. - TypeIndex OverriddenVFTable; // VFTable that this overrides. - ulittle32_t VFPtrOffset; // VFPtr offset in CompleteClass - ulittle32_t NamesLen; // Length of subsequent names array in bytes. - // Names: A sequence of null-terminated strings. First string is vftable - // names. - }; - }; // LF_ONEMETHOD @@ -941,46 +697,35 @@ class OneMethodRecord : public TypeRecord { public: OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {} explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} - OneMethodRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options, - MemberAccess Access, int32_t VFTableOffset, StringRef Name) - : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Kind(Kind), - Options(Options), Access(Access), VFTableOffset(VFTableOffset), - Name(Name) {} + OneMethodRecord(TypeIndex Type, MemberAttributes Attrs, int32_t VFTableOffset, + StringRef Name) + : TypeRecord(TypeRecordKind::OneMethod), Type(Type), Attrs(Attrs), + VFTableOffset(VFTableOffset), Name(Name) {} + OneMethodRecord(TypeIndex Type, MemberAccess Access, MethodKind Kind, + MethodOptions Options, int32_t VFTableOffset, StringRef Name) + : TypeRecord(TypeRecordKind::OneMethod), Type(Type), + Attrs(Access, Kind, Options), VFTableOffset(VFTableOffset), Name(Name) { + } /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getType() const { return Type; } - MethodKind getKind() const { return Kind; } - MethodOptions getOptions() const { return Options; } - MemberAccess getAccess() const { return Access; } + MethodKind getKind() const { return Attrs.getMethodKind(); } + MethodOptions getOptions() const { return Attrs.getFlags(); } + MemberAccess getAccess() const { return Attrs.getAccess(); } int32_t getVFTableOffset() const { return VFTableOffset; } StringRef getName() const { return Name; } bool isIntroducingVirtual() const { - return Kind == MethodKind::IntroducingVirtual || - Kind == MethodKind::PureIntroducingVirtual; + return getKind() == MethodKind::IntroducingVirtual || + getKind() == MethodKind::PureIntroducingVirtual; } TypeIndex Type; - MethodKind Kind; - MethodOptions Options; - MemberAccess Access; + MemberAttributes Attrs; int32_t VFTableOffset; StringRef Name; - -private: - struct Layout { - MemberAttributes Attrs; - TypeIndex Type; - // If is introduced virtual method: - // VFTableOffset: int32_t offset in vftable - // Name: Null-terminated string - }; - }; // LF_METHODLIST @@ -994,22 +739,8 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected - deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); - ArrayRef getMethods() const { return Methods; } std::vector Methods; - -private: - struct Layout { - MemberAttributes Attrs; - ulittle16_t Padding; - - TypeIndex Type; - // If is introduced virtual method: - // VFTableOffset: int32_t offset in vftable - }; - }; /// For method overload sets. LF_METHOD @@ -1025,120 +756,85 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected - deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); - uint16_t getNumOverloads() const { return NumOverloads; } TypeIndex getMethodList() const { return MethodList; } StringRef getName() const { return Name; } uint16_t NumOverloads; TypeIndex MethodList; StringRef Name; - -private: - struct Layout { - ulittle16_t MethodCount; // Size of overload set - TypeIndex MethList; // Type index of methods in overload set - // Name: Null-terminated string - }; - }; // LF_MEMBER class DataMemberRecord : public TypeRecord { public: explicit DataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + DataMemberRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset, + StringRef Name) + : TypeRecord(TypeRecordKind::DataMember), Attrs(Attrs), Type(Type), + FieldOffset(Offset), Name(Name) {} DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset, StringRef Name) - : TypeRecord(TypeRecordKind::DataMember), Access(Access), Type(Type), + : TypeRecord(TypeRecordKind::DataMember), Attrs(Access), Type(Type), FieldOffset(Offset), Name(Name) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - - MemberAccess getAccess() const { return Access; } + MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getType() const { return Type; } uint64_t getFieldOffset() const { return FieldOffset; } StringRef getName() const { return Name; } - MemberAccess Access; + MemberAttributes Attrs; TypeIndex Type; uint64_t FieldOffset; StringRef Name; - -private: - struct Layout { - MemberAttributes Attrs; // Access control attributes, etc - TypeIndex Type; - // FieldOffset: LF_NUMERIC encoded byte offset - // Name: Null-terminated string - }; - }; // LF_STMEMBER class StaticDataMemberRecord : public TypeRecord { public: explicit StaticDataMemberRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + StaticDataMemberRecord(MemberAttributes Attrs, TypeIndex Type, StringRef Name) + : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Attrs), Type(Type), + Name(Name) {} StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name) - : TypeRecord(TypeRecordKind::StaticDataMember), Access(Access), - Type(Type), Name(Name) {} + : TypeRecord(TypeRecordKind::StaticDataMember), Attrs(Access), Type(Type), + Name(Name) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected - deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); - - MemberAccess getAccess() const { return Access; } + MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getType() const { return Type; } StringRef getName() const { return Name; } - MemberAccess Access; + MemberAttributes Attrs; TypeIndex Type; StringRef Name; - -private: - struct Layout { - MemberAttributes Attrs; // Access control attributes, etc - TypeIndex Type; - // Name: Null-terminated string - }; - }; // LF_ENUMERATE class EnumeratorRecord : public TypeRecord { public: explicit EnumeratorRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + EnumeratorRecord(MemberAttributes Attrs, APSInt Value, StringRef Name) + : TypeRecord(TypeRecordKind::Enumerator), Attrs(Attrs), + Value(std::move(Value)), Name(Name) {} EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name) - : TypeRecord(TypeRecordKind::Enumerator), Access(Access), + : TypeRecord(TypeRecordKind::Enumerator), Attrs(Access), Value(std::move(Value)), Name(Name) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - - MemberAccess getAccess() const { return Access; } + MemberAccess getAccess() const { return Attrs.getAccess(); } APSInt getValue() const { return Value; } StringRef getName() const { return Name; } - MemberAccess Access; + MemberAttributes Attrs; APSInt Value; StringRef Name; - -private: - struct Layout { - MemberAttributes Attrs; // Access control attributes, etc - // EnumValue: LF_NUMERIC encoded enumerator value - // Name: Null-terminated string - }; - }; // LF_VFUNCTAB @@ -1152,85 +848,62 @@ public: /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - TypeIndex getType() const { return Type; } TypeIndex Type; - -private: - struct Layout { - ulittle16_t Pad0; - TypeIndex Type; // Type of vfptr - }; }; // LF_BCLASS, LF_BINTERFACE class BaseClassRecord : public TypeRecord { public: explicit BaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + BaseClassRecord(MemberAttributes Attrs, TypeIndex Type, uint64_t Offset) + : TypeRecord(TypeRecordKind::BaseClass), Attrs(Attrs), Type(Type), + Offset(Offset) {} BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset) - : TypeRecord(TypeRecordKind::BaseClass), Access(Access), Type(Type), + : TypeRecord(TypeRecordKind::BaseClass), Attrs(Access), Type(Type), Offset(Offset) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader); - - MemberAccess getAccess() const { return Access; } + MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getBaseType() const { return Type; } uint64_t getBaseOffset() const { return Offset; } - MemberAccess Access; + MemberAttributes Attrs; TypeIndex Type; uint64_t Offset; - -private: - struct Layout { - MemberAttributes Attrs; // Access control attributes, etc - TypeIndex BaseType; // Base class type - // BaseOffset: LF_NUMERIC encoded byte offset of base from derived. - }; }; // LF_VBCLASS, LF_IVBCLASS class VirtualBaseClassRecord : public TypeRecord { public: explicit VirtualBaseClassRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + VirtualBaseClassRecord(TypeRecordKind Kind, MemberAttributes Attrs, + TypeIndex BaseType, TypeIndex VBPtrType, + uint64_t Offset, uint64_t Index) + : TypeRecord(Kind), Attrs(Attrs), BaseType(BaseType), + VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {} VirtualBaseClassRecord(TypeRecordKind Kind, MemberAccess Access, TypeIndex BaseType, TypeIndex VBPtrType, uint64_t Offset, uint64_t Index) - : TypeRecord(Kind), Access(Access), BaseType(BaseType), + : TypeRecord(Kind), Attrs(Access), BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset), VTableIndex(Index) {} /// Rewrite member type indices with IndexMap. Returns false if a type index /// is not in the map. bool remapTypeIndices(ArrayRef IndexMap); - static Expected - deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); - - MemberAccess getAccess() const { return Access; } + MemberAccess getAccess() const { return Attrs.getAccess(); } TypeIndex getBaseType() const { return BaseType; } TypeIndex getVBPtrType() const { return VBPtrType; } uint64_t getVBPtrOffset() const { return VBPtrOffset; } uint64_t getVTableIndex() const { return VTableIndex; } - MemberAccess Access; + MemberAttributes Attrs; TypeIndex BaseType; TypeIndex VBPtrType; uint64_t VBPtrOffset; uint64_t VTableIndex; - -private: - struct Layout { - MemberAttributes Attrs; // Access control attributes, etc. - TypeIndex BaseType; // Base class type - TypeIndex VBPtrType; // Virtual base pointer type - // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC. - // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC. - }; }; /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records @@ -1246,15 +919,7 @@ public: bool remapTypeIndices(ArrayRef IndexMap); - static Expected - deserialize(TypeRecordKind Kind, msf::StreamReader &Reader); TypeIndex ContinuationIndex; - -private: - struct Layout { - ulittle16_t Pad0; - TypeIndex ContinuationIndex; - }; }; } diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h new file mode 100644 index 00000000000..970f345e0af --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h @@ -0,0 +1,46 @@ +//===- TypeRecordMapping.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDMAPPING_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDMAPPING_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { +class TypeRecordMapping : public TypeVisitorCallbacks { +public: + explicit TypeRecordMapping(msf::StreamReader &Reader) : IO(Reader) {} + + Error visitTypeBegin(CVType &Record) override; + Error visitTypeEnd(CVType &Record) override; + + Error visitMemberBegin(CVMemberRecord &Record) override; + Error visitMemberEnd(CVMemberRecord &Record) override; + +#define TYPE_RECORD(EnumName, EnumVal, Name) \ + Error visitKnownRecord(CVType &CVR, Name##Record &Record) override; +#define MEMBER_RECORD(EnumName, EnumVal, Name) \ + Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override; +#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "TypeRecords.def" + +private: + Optional TypeKind; + + CodeViewRecordIO IO; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/MSF/StreamWriter.h b/include/llvm/DebugInfo/MSF/StreamWriter.h index 88043c737bd..1b3bc32d6ac 100644 --- a/include/llvm/DebugInfo/MSF/StreamWriter.h +++ b/include/llvm/DebugInfo/MSF/StreamWriter.h @@ -25,11 +25,18 @@ namespace msf { class StreamWriter { public: + StreamWriter() {} StreamWriter(WritableStreamRef Stream); Error writeBytes(ArrayRef Buffer); + Error writeInteger(uint8_t Int); Error writeInteger(uint16_t Dest); Error writeInteger(uint32_t Dest); + Error writeInteger(uint64_t Dest); + Error writeInteger(int8_t Int); + Error writeInteger(int16_t Dest); + Error writeInteger(int32_t Dest); + Error writeInteger(int64_t Dest); Error writeZeroString(StringRef Str); Error writeFixedString(StringRef Str); Error writeStreamRef(ReadableStreamRef Ref); @@ -77,7 +84,7 @@ public: private: WritableStreamRef Stream; - uint32_t Offset; + uint32_t Offset = 0; }; } // namespace msf } // namespace llvm diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 5cc8b4e4555..fc691456a48 100644 --- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1690,9 +1690,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, HfaKind::None, WindowsRTClassKind::None, TypeIndex(), - TypeIndex(), TypeIndex(), 0, FullName, Ty->getIdentifier())); + TypeIndex FwdDeclTI = TypeTable.writeKnownType( + ClassRecord(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0, + FullName, Ty->getIdentifier())); if (!Ty->isForwardDecl()) DeferredCompleteTypes.push_back(Ty); return FwdDeclTI; @@ -1716,9 +1716,9 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) { uint64_t SizeInBytes = Ty->getSizeInBits() / 8; - TypeIndex ClassTI = TypeTable.writeKnownType(ClassRecord( - Kind, FieldCount, CO, HfaKind::None, WindowsRTClassKind::None, FieldTI, - TypeIndex(), VShapeTI, SizeInBytes, FullName, Ty->getIdentifier())); + TypeIndex ClassTI = TypeTable.writeKnownType( + ClassRecord(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI, + SizeInBytes, FullName, Ty->getIdentifier())); TypeTable.writeKnownType(UdtSourceLineRecord( ClassTI, TypeTable.writeKnownType(StringIdRecord( @@ -1734,8 +1734,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, HfaKind::None, TypeIndex(), 0, FullName, Ty->getIdentifier())); + TypeIndex FwdDeclTI = TypeTable.writeKnownType( + UnionRecord(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier())); if (!Ty->isForwardDecl()) DeferredCompleteTypes.push_back(Ty); return FwdDeclTI; @@ -1755,9 +1755,8 @@ TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) { uint64_t SizeInBytes = Ty->getSizeInBits() / 8; std::string FullName = getFullyQualifiedName(Ty); - TypeIndex UnionTI = TypeTable.writeKnownType( - UnionRecord(FieldCount, CO, HfaKind::None, FieldTI, SizeInBytes, FullName, - Ty->getIdentifier())); + TypeIndex UnionTI = TypeTable.writeKnownType(UnionRecord( + FieldCount, CO, FieldTI, SizeInBytes, FullName, Ty->getIdentifier())); TypeTable.writeKnownType(UdtSourceLineRecord( UnionTI, TypeTable.writeKnownType(StringIdRecord( @@ -1858,11 +1857,10 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { if (Introduced) VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes(); - Methods.push_back( - OneMethodRecord(MethodType, translateMethodKindFlags(SP, Introduced), - translateMethodOptionFlags(SP), - translateAccessFlags(Ty->getTag(), SP->getFlags()), - VFTableOffset, Name)); + Methods.push_back(OneMethodRecord( + MethodType, translateAccessFlags(Ty->getTag(), SP->getFlags()), + translateMethodKindFlags(SP, Introduced), + translateMethodOptionFlags(SP), VFTableOffset, Name)); MemberCount++; } assert(Methods.size() > 0 && "Empty methods map entry"); diff --git a/lib/DebugInfo/CodeView/CMakeLists.txt b/lib/DebugInfo/CodeView/CMakeLists.txt index a0700804301..4bbc48d111f 100644 --- a/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/lib/DebugInfo/CodeView/CMakeLists.txt @@ -1,5 +1,6 @@ add_llvm_library(LLVMDebugInfoCodeView CodeViewError.cpp + CodeViewRecordIO.cpp CVSymbolVisitor.cpp CVTypeVisitor.cpp EnumTables.cpp @@ -15,6 +16,7 @@ add_llvm_library(LLVMDebugInfoCodeView TypeDumper.cpp TypeRecord.cpp TypeRecordBuilder.cpp + TypeRecordMapping.cpp TypeStreamMerger.cpp TypeTableBuilder.cpp diff --git a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp index 2dee8988df9..5f5d5fe35ef 100644 --- a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -10,44 +10,29 @@ #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/MSF/ByteStream.h" using namespace llvm; using namespace llvm::codeview; -static Error skipPadding(msf::StreamReader &Reader) { - if (Reader.empty()) - return Error::success(); - - uint8_t Leaf = Reader.peek(); - if (Leaf < LF_PAD0) - return Error::success(); - // Leaf is greater than 0xf0. We should advance by the number of bytes in - // the low 4 bits. - unsigned BytesToAdvance = Leaf & 0x0F; - return Reader.skip(BytesToAdvance); -} - template static Expected -deserializeMemberRecord(msf::StreamReader &Reader, TypeLeafKind Kind) { - msf::StreamReader OldReader = Reader; - TypeRecordKind RK = static_cast(Kind); - auto ExpectedRecord = T::deserialize(RK, Reader); - if (!ExpectedRecord) - return ExpectedRecord.takeError(); - assert(Reader.bytesRemaining() < OldReader.bytesRemaining()); - if (auto EC = skipPadding(Reader)) +deserializeMemberRecord(FieldListDeserializer &Deserializer, + msf::StreamReader &Reader, TypeLeafKind Kind) { + T MR(static_cast(Kind)); + CVMemberRecord CVR; + CVR.Kind = Kind; + + if (auto EC = Deserializer.visitMemberBegin(CVR)) + return std::move(EC); + if (auto EC = Deserializer.visitKnownMember(CVR, MR)) + return std::move(EC); + if (auto EC = Deserializer.visitMemberEnd(CVR)) return std::move(EC); - CVMemberRecord CVMR; - CVMR.Kind = Kind; - - uint32_t RecordLength = OldReader.bytesRemaining() - Reader.bytesRemaining(); - if (auto EC = OldReader.readBytes(CVMR.Data, RecordLength)) - return std::move(EC); - - return CVMR; + return CVR; } CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks) @@ -138,22 +123,28 @@ Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) { } template -static Error visitKnownMember(msf::StreamReader &Reader, TypeLeafKind Leaf, +static Error visitKnownMember(FieldListDeserializer &Deserializer, + msf::StreamReader &Reader, TypeLeafKind Leaf, TypeVisitorCallbacks &Callbacks) { - auto ExpectedRecord = deserializeMemberRecord(Reader, Leaf); - if (!ExpectedRecord) - return ExpectedRecord.takeError(); - CVMemberRecord &Record = *ExpectedRecord; - if (auto EC = Callbacks.visitMemberBegin(Record)) + MR Record(static_cast(Leaf)); + CVMemberRecord CVR; + CVR.Kind = Leaf; + + if (auto EC = Callbacks.visitMemberBegin(CVR)) return EC; - if (auto EC = visitKnownMember(Record, Callbacks)) + if (auto EC = Callbacks.visitKnownMember(CVR, Record)) return EC; - if (auto EC = Callbacks.visitMemberEnd(Record)) + if (auto EC = Callbacks.visitMemberEnd(CVR)) return EC; return Error::success(); } Error CVTypeVisitor::visitFieldListMemberStream(msf::StreamReader Reader) { + FieldListDeserializer Deserializer(Reader); + TypeVisitorCallbackPipeline Pipeline; + Pipeline.addCallbackToPipeline(Deserializer); + Pipeline.addCallbackToPipeline(Callbacks); + TypeLeafKind Leaf; while (!Reader.empty()) { if (auto EC = Reader.readEnum(Leaf)) @@ -168,7 +159,8 @@ Error CVTypeVisitor::visitFieldListMemberStream(msf::StreamReader Reader) { cv_error_code::unknown_member_record); #define MEMBER_RECORD(EnumName, EnumVal, Name) \ case EnumName: { \ - if (auto EC = visitKnownMember(Reader, Leaf, Callbacks)) \ + if (auto EC = visitKnownMember(Deserializer, Reader, Leaf, \ + Pipeline)) \ return EC; \ break; \ } diff --git a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp new file mode 100644 index 00000000000..7841e4f2f6a --- /dev/null +++ b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp @@ -0,0 +1,186 @@ +//===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/RecordSerialization.h" +#include "llvm/DebugInfo/MSF/StreamReader.h" +#include "llvm/DebugInfo/MSF/StreamWriter.h" + +using namespace llvm; +using namespace llvm::codeview; + +Error CodeViewRecordIO::beginRecord(uint16_t Kind) { + assert(!CurrentRecord.hasValue() && "There is already a record active!"); + CurrentRecord.emplace(); + + CurrentRecord->Kind = Kind; + return Error::success(); +} + +Error CodeViewRecordIO::endRecord() { + assert(CurrentRecord.hasValue() && "Not in a record!"); + CurrentRecord.reset(); + return Error::success(); +} + +Error CodeViewRecordIO::skipPadding() { + assert(!isWriting() && "Cannot skip padding while writing!"); + + if (Reader->bytesRemaining() == 0) + return Error::success(); + + uint8_t Leaf = Reader->peek(); + if (Leaf < LF_PAD0) + return Error::success(); + // Leaf is greater than 0xf0. We should advance by the number of bytes in + // the low 4 bits. + unsigned BytesToAdvance = Leaf & 0x0F; + return Reader->skip(BytesToAdvance); +} + +Error CodeViewRecordIO::mapByteVectorTail(ArrayRef &Bytes) { + if (isWriting()) { + if (auto EC = Writer->writeBytes(Bytes)) + return EC; + } else { + if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining())) + return EC; + } + return Error::success(); +} + +Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) { + if (isWriting()) { + if (auto EC = Writer->writeInteger(TypeInd.getIndex())) + return EC; + return Error::success(); + } + + uint32_t I; + if (auto EC = Reader->readInteger(I)) + return EC; + TypeInd.setIndex(I); + return Error::success(); +} + +Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { + if (isWriting()) { + if (Value >= 0) { + if (auto EC = writeEncodedUnsignedInteger(static_cast(Value))) + return EC; + } else { + if (auto EC = writeEncodedSignedInteger(Value)) + return EC; + } + } else { + APSInt N; + if (auto EC = consume(*Reader, N)) + return EC; + Value = N.getExtValue(); + } + + return Error::success(); +} + +Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { + if (isWriting()) { + if (auto EC = writeEncodedUnsignedInteger(Value)) + return EC; + } else { + APSInt N; + if (auto EC = consume(*Reader, N)) + return EC; + Value = N.getZExtValue(); + } + return Error::success(); +} + +Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { + if (isWriting()) { + if (Value.isSigned()) + return writeEncodedSignedInteger(Value.getSExtValue()); + return writeEncodedUnsignedInteger(Value.getZExtValue()); + } + + return consume(*Reader, Value); +} + +Error CodeViewRecordIO::mapStringZ(StringRef &Value) { + if (isWriting()) { + if (auto EC = Writer->writeZeroString(Value)) + return EC; + } else { + if (auto EC = Reader->readZeroString(Value)) + return EC; + } + return Error::success(); +} + +Error CodeViewRecordIO::mapGuid(StringRef &Guid) { + if (isWriting()) { + assert(Guid.size() == 16 && "Invalid Guid Size!"); + if (auto EC = Writer->writeFixedString(Guid)) + return EC; + } else { + if (auto EC = Reader->readFixedString(Guid, 16)) + return EC; + } + return Error::success(); +} + +Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { + assert(Value < 0 && "Encoded integer is not signed!"); + if (Value >= std::numeric_limits::min()) { + if (auto EC = Writer->writeInteger(static_cast(LF_CHAR))) + return EC; + if (auto EC = Writer->writeInteger(static_cast(Value))) + return EC; + } else if (Value >= std::numeric_limits::min()) { + if (auto EC = Writer->writeInteger(static_cast(LF_SHORT))) + return EC; + if (auto EC = Writer->writeInteger(static_cast(Value))) + return EC; + } else if (Value >= std::numeric_limits::min()) { + if (auto EC = Writer->writeInteger(static_cast(LF_LONG))) + return EC; + if (auto EC = Writer->writeInteger(static_cast(Value))) + return EC; + } else { + if (auto EC = Writer->writeInteger(static_cast(LF_QUADWORD))) + return EC; + if (auto EC = Writer->writeInteger(Value)) + return EC; + } + return Error::success(); +} + +Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) { + if (Value < LF_NUMERIC) { + if (auto EC = Writer->writeInteger(static_cast(Value))) + return EC; + } else if (Value <= std::numeric_limits::max()) { + if (auto EC = Writer->writeInteger(static_cast(LF_USHORT))) + return EC; + if (auto EC = Writer->writeInteger(static_cast(Value))) + return EC; + } else if (Value <= std::numeric_limits::max()) { + if (auto EC = Writer->writeInteger(static_cast(LF_ULONG))) + return EC; + if (auto EC = Writer->writeInteger(static_cast(Value))) + return EC; + } else { + if (auto EC = Writer->writeInteger(static_cast(LF_UQUADWORD))) + return EC; + if (auto EC = Writer->writeInteger(Value)) + return EC; + } + + return Error::success(); +} diff --git a/lib/DebugInfo/CodeView/TypeDumper.cpp b/lib/DebugInfo/CodeView/TypeDumper.cpp index 1e7af16e841..84abad91c53 100644 --- a/lib/DebugInfo/CodeView/TypeDumper.cpp +++ b/lib/DebugInfo/CodeView/TypeDumper.cpp @@ -268,12 +268,7 @@ Error CVTypeDumper::visitMemberEnd(CVMemberRecord &Record) { Error CVTypeDumper::visitKnownRecord(CVRecord &CVR, FieldListRecord &FieldList) { - TypeDeserializer Deserializer; - TypeVisitorCallbackPipeline Pipeline; - Pipeline.addCallbackToPipeline(Deserializer); - Pipeline.addCallbackToPipeline(*this); - - CVTypeVisitor Visitor(Pipeline); + CVTypeVisitor Visitor(*this); if (auto EC = Visitor.visitFieldListMemberStream(FieldList.Data)) return EC; diff --git a/lib/DebugInfo/CodeView/TypeRecord.cpp b/lib/DebugInfo/CodeView/TypeRecord.cpp index 7a2dc8fa803..b951c068ca8 100644 --- a/lib/DebugInfo/CodeView/TypeRecord.cpp +++ b/lib/DebugInfo/CodeView/TypeRecord.cpp @@ -16,384 +16,6 @@ using namespace llvm; using namespace llvm::codeview; -//===----------------------------------------------------------------------===// -// Type record deserialization -//===----------------------------------------------------------------------===// - -Expected -MemberPointerInfo::deserialize(msf::StreamReader &Reader) { - const Layout *L = nullptr; - if (auto EC = Reader.readObject(L)) - return std::move(EC); - - TypeIndex T = L->ClassType; - uint16_t R = L->Representation; - PointerToMemberRepresentation PMR = - static_cast(R); - return MemberPointerInfo(T, PMR); -} - -Expected -ModifierRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - if (auto EC = Reader.readObject(L)) - return std::move(EC); - - TypeIndex M = L->ModifiedType; - uint16_t O = L->Modifiers; - ModifierOptions MO = static_cast(O); - return ModifierRecord(M, MO); -} - -Expected -ProcedureRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - if (auto EC = Reader.readObject(L)) - return std::move(EC); - return ProcedureRecord(L->ReturnType, L->CallConv, L->Options, - L->NumParameters, L->ArgListType); -} - -Expected -MemberFunctionRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - CV_DESERIALIZE(Reader, L); - return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType, - L->CallConv, L->Options, L->NumParameters, - L->ArgListType, L->ThisAdjustment); -} - -Expected -MemberFuncIdRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return MemberFuncIdRecord(L->ClassType, L->FunctionType, Name); -} - -Expected ArgListRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList) - return make_error( - cv_error_code::corrupt_record, - "ArgListRecord contains unexpected TypeRecordKind"); - - const Layout *L = nullptr; - ArrayRef Indices; - CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); - return ArgListRecord(Kind, Indices); -} - -Expected PointerRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - if (auto EC = Reader.readObject(L)) - return std::move(EC); - - PointerKind PtrKind = L->getPtrKind(); - PointerMode Mode = L->getPtrMode(); - uint32_t Opts = L->Attrs; - PointerOptions Options = static_cast(Opts); - uint8_t Size = L->getPtrSize(); - - if (L->isPointerToMember()) { - if (auto ExpectedMPI = MemberPointerInfo::deserialize(Reader)) - return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, - *ExpectedMPI); - else - return ExpectedMPI.takeError(); - } - - return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size); -} - -Expected -NestedTypeRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return NestedTypeRecord(L->Type, Name); -} - -Expected -FieldListRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - ArrayRef Data; - if (auto EC = Reader.readBytes(Data, Reader.bytesRemaining())) - return std::move(EC); - return FieldListRecord(Data); -} - -Expected ArrayRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - uint64_t Size; - StringRef Name; - CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name); - return ArrayRecord(L->ElementType, L->IndexType, Size, Name); -} - -Expected ClassRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - uint64_t Size = 0; - StringRef Name; - StringRef UniqueName; - uint16_t Props; - const Layout *L = nullptr; - - CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name, - CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); - - Props = L->Properties; - uint16_t WrtValue = (Props & WinRTKindMask) >> WinRTKindShift; - WindowsRTClassKind WRT = static_cast(WrtValue); - uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift; - HfaKind Hfa = static_cast(HfaMask); - - ClassOptions Options = static_cast(Props); - return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList, - L->DerivedFrom, L->VShape, Size, Name, UniqueName); -} - -Expected UnionRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - uint64_t Size = 0; - StringRef Name; - StringRef UniqueName; - uint16_t Props; - - const Layout *L = nullptr; - CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Size), Name, - CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); - - Props = L->Properties; - - uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift; - HfaKind Hfa = static_cast(HfaMask); - ClassOptions Options = static_cast(Props); - return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name, - UniqueName); -} - -Expected EnumRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - StringRef UniqueName; - CV_DESERIALIZE(Reader, L, Name, - CV_CONDITIONAL_FIELD(UniqueName, L->hasUniqueName())); - - uint16_t P = L->Properties; - ClassOptions Options = static_cast(P); - return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name, - UniqueName, L->UnderlyingType); -} - -Expected -BitFieldRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - CV_DESERIALIZE(Reader, L); - return BitFieldRecord(L->Type, L->BitSize, L->BitOffset); -} - -Expected -VFTableShapeRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - if (auto EC = Reader.readObject(L)) - return std::move(EC); - - std::vector Slots; - uint16_t Count = L->VFEntryCount; - while (Count > 0) { - // Process up to 2 nibbles at a time (if there are at least 2 remaining) - uint8_t Data; - if (auto EC = Reader.readInteger(Data)) - return std::move(EC); - - uint8_t Value = Data & 0x0F; - Slots.push_back(static_cast(Value)); - if (--Count > 0) { - Value = (Data & 0xF0) >> 4; - Slots.push_back(static_cast(Value)); - --Count; - } - } - - return VFTableShapeRecord(Slots); -} - -Expected -TypeServer2Record::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name); -} - -Expected -StringIdRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return StringIdRecord(L->id, Name); -} - -Expected FuncIdRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return FuncIdRecord(L->ParentScope, L->FunctionType, Name); -} - -Expected -UdtSourceLineRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - CV_DESERIALIZE(Reader, L); - return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber); -} - -Expected -BuildInfoRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - ArrayRef Indices; - CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs)); - return BuildInfoRecord(Indices); -} - -Expected VFTableRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - std::vector Names; - CV_DESERIALIZE(Reader, L, Name, CV_ARRAY_FIELD_TAIL(Names)); - return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset, - Name, Names); -} - -Expected -OneMethodRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - int32_t VFTableOffset = -1; - - CV_DESERIALIZE(Reader, L, CV_CONDITIONAL_FIELD( - VFTableOffset, L->Attrs.isIntroducedVirtual()), - Name); - - MethodOptions Options = L->Attrs.getFlags(); - MethodKind MethKind = L->Attrs.getMethodKind(); - MemberAccess Access = L->Attrs.getAccess(); - OneMethodRecord Method(L->Type, MethKind, Options, Access, VFTableOffset, - Name); - // Validate the vftable offset. - if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0) - return make_error(cv_error_code::corrupt_record, - "Invalid VFTableOffset"); - return Method; -} - -Expected -MethodOverloadListRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - std::vector Methods; - while (!Reader.empty()) { - const Layout *L = nullptr; - int32_t VFTableOffset = -1; - CV_DESERIALIZE( - Reader, L, - CV_CONDITIONAL_FIELD(VFTableOffset, L->Attrs.isIntroducedVirtual())); - - MethodOptions Options = L->Attrs.getFlags(); - MethodKind MethKind = L->Attrs.getMethodKind(); - MemberAccess Access = L->Attrs.getAccess(); - - Methods.emplace_back(L->Type, MethKind, Options, Access, VFTableOffset, - StringRef()); - - // Validate the vftable offset. - auto &Method = Methods.back(); - if (Method.isIntroducingVirtual() && Method.getVFTableOffset() < 0) - return make_error(cv_error_code::corrupt_record, - "Invalid VFTableOffset"); - } - return MethodOverloadListRecord(Methods); -} - -Expected -OverloadedMethodRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return OverloadedMethodRecord(L->MethodCount, L->MethList, Name); -} - -Expected -DataMemberRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - uint64_t Offset; - StringRef Name; - CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset), Name); - return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name); -} - -Expected -StaticDataMemberRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - StringRef Name; - CV_DESERIALIZE(Reader, L, Name); - return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name); -} - -Expected -EnumeratorRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - APSInt Value; - StringRef Name; - CV_DESERIALIZE(Reader, L, Value, Name); - return EnumeratorRecord(L->Attrs.getAccess(), Value, Name); -} - -Expected VFPtrRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - if (auto EC = Reader.readObject(L)) - return std::move(EC); - return VFPtrRecord(L->Type); -} - -Expected -BaseClassRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) { - const Layout *L = nullptr; - uint64_t Offset; - CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset)); - return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset); -} - -Expected -VirtualBaseClassRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - uint64_t Offset; - uint64_t Index; - CV_DESERIALIZE(Reader, L, CV_NUMERIC_FIELD(Offset), CV_NUMERIC_FIELD(Index)); - return VirtualBaseClassRecord(Kind, L->Attrs.getAccess(), L->BaseType, - L->VBPtrType, Offset, Index); -} - -Expected -ListContinuationRecord::deserialize(TypeRecordKind Kind, - msf::StreamReader &Reader) { - const Layout *L = nullptr; - CV_DESERIALIZE(Reader, L); - return ListContinuationRecord(L->ContinuationIndex); -} - //===----------------------------------------------------------------------===// // Type index remapping //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp new file mode 100644 index 00000000000..d85a643c6d2 --- /dev/null +++ b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp @@ -0,0 +1,417 @@ +//===- TypeRecordMapping.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h" + +using namespace llvm; +using namespace llvm::codeview; + +#define error(X) \ + if (auto EC = X) \ + return EC; + +namespace { +struct MapStringZ { + Error operator()(CodeViewRecordIO &IO, StringRef &S) const { + return IO.mapStringZ(S); + } +}; + +struct MapInteger { + template Error operator()(CodeViewRecordIO &IO, T &N) const { + return IO.mapInteger(N); + } +}; + +struct MapEnum { + template Error operator()(CodeViewRecordIO &IO, T &N) const { + return IO.mapEnum(N); + } +}; + +struct MapOneMethodRecord { + explicit MapOneMethodRecord(bool IsFromOverloadList) + : IsFromOverloadList(IsFromOverloadList) {} + + Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const { + error(IO.mapInteger(Method.Attrs.Attrs)); + if (IsFromOverloadList) { + uint16_t Padding = 0; + error(IO.mapInteger(Padding)); + } + error(IO.mapInteger(Method.Type)); + if (Method.isIntroducingVirtual()) { + error(IO.mapInteger(Method.VFTableOffset)); + } else if (!IO.isWriting()) + Method.VFTableOffset = -1; + + if (!IsFromOverloadList) + error(IO.mapStringZ(Method.Name)); + + return Error::success(); + } + +private: + bool IsFromOverloadList; +}; +} + +static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, + StringRef &UniqueName, bool HasUniqueName) { + error(IO.mapStringZ(Name)); + if (HasUniqueName) + error(IO.mapStringZ(UniqueName)); + + return Error::success(); +} + +Error TypeRecordMapping::visitTypeBegin(CVType &CVR) { + error(IO.beginRecord(CVR.Type)); + TypeKind = CVR.Type; + return Error::success(); +} + +Error TypeRecordMapping::visitTypeEnd(CVType &Record) { + error(IO.endRecord()); + TypeKind.reset(); + return Error::success(); +} + +Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) { + return Error::success(); +} + +Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) { + if (!IO.isWriting()) { + if (auto EC = IO.skipPadding()) + return EC; + } + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) { + error(IO.mapInteger(Record.ModifiedType)); + error(IO.mapEnum(Record.Modifiers)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + ProcedureRecord &Record) { + error(IO.mapInteger(Record.ReturnType)); + error(IO.mapEnum(Record.CallConv)); + error(IO.mapEnum(Record.Options)); + error(IO.mapInteger(Record.ParameterCount)); + error(IO.mapInteger(Record.ArgumentList)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + MemberFunctionRecord &Record) { + error(IO.mapInteger(Record.ReturnType)); + error(IO.mapInteger(Record.ClassType)); + error(IO.mapInteger(Record.ThisType)); + error(IO.mapEnum(Record.CallConv)); + error(IO.mapEnum(Record.Options)); + error(IO.mapInteger(Record.ParameterCount)); + error(IO.mapInteger(Record.ArgumentList)); + error(IO.mapInteger(Record.ThisPointerAdjustment)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArgListRecord &Record) { + error(IO.mapVectorN(Record.StringIndices, MapInteger())); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) { + error(IO.mapInteger(Record.ReferentType)); + error(IO.mapInteger(Record.Attrs)); + + if (Record.isPointerToMember()) { + if (!IO.isWriting()) + Record.MemberInfo.emplace(); + + MemberPointerInfo &M = *Record.MemberInfo; + error(IO.mapInteger(M.ContainingType)); + error(IO.mapEnum(M.Representation)); + } + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) { + error(IO.mapInteger(Record.ElementType)); + error(IO.mapInteger(Record.IndexType)); + error(IO.mapEncodedInteger(Record.Size)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) { + assert((CVR.Type == TypeLeafKind::LF_STRUCTURE) || + (CVR.Type == TypeLeafKind::LF_CLASS) || + (CVR.Type == TypeLeafKind::LF_INTERFACE)); + + error(IO.mapInteger(Record.MemberCount)); + error(IO.mapEnum(Record.Options)); + error(IO.mapInteger(Record.FieldList)); + error(IO.mapInteger(Record.DerivationList)); + error(IO.mapInteger(Record.VTableShape)); + error(IO.mapEncodedInteger(Record.Size)); + error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, + Record.hasUniqueName())); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) { + error(IO.mapInteger(Record.MemberCount)); + error(IO.mapEnum(Record.Options)); + error(IO.mapInteger(Record.FieldList)); + error(IO.mapEncodedInteger(Record.Size)); + error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, + Record.hasUniqueName())); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) { + error(IO.mapInteger(Record.MemberCount)); + error(IO.mapEnum(Record.Options)); + error(IO.mapInteger(Record.UnderlyingType)); + error(IO.mapInteger(Record.FieldList)); + error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, + Record.hasUniqueName())); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) { + error(IO.mapInteger(Record.Type)); + error(IO.mapInteger(Record.BitSize)); + error(IO.mapInteger(Record.BitOffset)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + VFTableShapeRecord &Record) { + uint16_t Size; + if (IO.isWriting()) { + ArrayRef Slots = Record.getSlots(); + Size = Slots.size(); + error(IO.mapInteger(Size)); + + for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) { + uint8_t Byte = static_cast(Slots[SlotIndex]) << 4; + if ((SlotIndex + 1) < Slots.size()) { + Byte |= static_cast(Slots[SlotIndex + 1]); + } + error(IO.mapInteger(Byte)); + } + } else { + error(IO.mapInteger(Size)); + for (uint16_t I = 0; I < Size; I += 2) { + uint8_t Byte; + error(IO.mapInteger(Byte)); + Record.Slots.push_back(static_cast(Byte & 0xF)); + if ((I + 1) < Size) + Record.Slots.push_back(static_cast(Byte >> 4)); + } + } + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableRecord &Record) { + error(IO.mapInteger(Record.CompleteClass)); + error(IO.mapInteger(Record.OverriddenVFTable)); + error(IO.mapInteger(Record.VFPtrOffset)); + uint32_t NamesLen = 0; + if (IO.isWriting()) { + for (auto Name : Record.MethodNames) + NamesLen += Name.size() + 1; + } + error(IO.mapInteger(NamesLen)); + error(IO.mapVectorTail(Record.MethodNames, MapStringZ())); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringIdRecord &Record) { + error(IO.mapInteger(Record.Id)); + error(IO.mapStringZ(Record.String)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + UdtSourceLineRecord &Record) { + error(IO.mapInteger(Record.UDT)); + error(IO.mapInteger(Record.SourceFile)); + error(IO.mapInteger(Record.LineNumber)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + UdtModSourceLineRecord &Record) { + error(IO.mapInteger(Record.UDT)); + error(IO.mapInteger(Record.SourceFile)); + error(IO.mapInteger(Record.LineNumber)); + error(IO.mapInteger(Record.Module)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, FuncIdRecord &Record) { + error(IO.mapInteger(Record.ParentScope)); + error(IO.mapInteger(Record.FunctionType)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + MemberFuncIdRecord &Record) { + error(IO.mapInteger(Record.ClassType)); + error(IO.mapInteger(Record.FunctionType)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + BuildInfoRecord &Record) { + error(IO.mapVectorN(Record.ArgIndices, MapInteger())); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + MethodOverloadListRecord &Record) { + // TODO: Split the list into multiple records if it's longer than 64KB, using + // a subrecord of TypeRecordKind::Index to chain the records together. + error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true))); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + FieldListRecord &Record) { + error(IO.mapByteVectorTail(Record.Data)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, + TypeServer2Record &Record) { + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + BaseClassRecord &Record) { + error(IO.mapInteger(Record.Attrs.Attrs)); + error(IO.mapInteger(Record.Type)); + error(IO.mapEncodedInteger(Record.Offset)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + EnumeratorRecord &Record) { + error(IO.mapInteger(Record.Attrs.Attrs)); + + // FIXME: Handle full APInt such as __int128. + error(IO.mapEncodedInteger(Record.Value)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + DataMemberRecord &Record) { + error(IO.mapInteger(Record.Attrs.Attrs)); + error(IO.mapInteger(Record.Type)); + error(IO.mapEncodedInteger(Record.FieldOffset)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + OverloadedMethodRecord &Record) { + error(IO.mapInteger(Record.NumOverloads)); + error(IO.mapInteger(Record.MethodList)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + OneMethodRecord &Record) { + MapOneMethodRecord Mapper(false); + return Mapper(IO, Record); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + NestedTypeRecord &Record) { + uint16_t Padding = 0; + error(IO.mapInteger(Padding)); + error(IO.mapInteger(Record.Type)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + StaticDataMemberRecord &Record) { + + error(IO.mapInteger(Record.Attrs.Attrs)); + error(IO.mapInteger(Record.Type)); + error(IO.mapStringZ(Record.Name)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + VirtualBaseClassRecord &Record) { + + error(IO.mapInteger(Record.Attrs.Attrs)); + error(IO.mapInteger(Record.BaseType)); + error(IO.mapInteger(Record.VBPtrType)); + error(IO.mapEncodedInteger(Record.VBPtrOffset)); + error(IO.mapEncodedInteger(Record.VTableIndex)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + VFPtrRecord &Record) { + uint16_t Padding = 0; + error(IO.mapInteger(Padding)); + error(IO.mapInteger(Record.Type)); + + return Error::success(); +} + +Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, + ListContinuationRecord &Record) { + uint16_t Padding = 0; + error(IO.mapInteger(Padding)); + error(IO.mapInteger(Record.ContinuationIndex)); + + return Error::success(); +} diff --git a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index acd7f74a3cc..551a98a67c8 100644 --- a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -84,14 +84,7 @@ private: } Error visitKnownRecordImpl(FieldListRecord &Record) { - // Don't do anything, this will get written in the call to visitTypeEnd(). - TypeVisitorCallbackPipeline Pipeline; - TypeDeserializer Deserializer; - - Pipeline.addCallbackToPipeline(Deserializer); - Pipeline.addCallbackToPipeline(*this); - - CVTypeVisitor Visitor(Pipeline); + CVTypeVisitor Visitor(*this); if (auto EC = Visitor.visitFieldListMemberStream(Record.Data)) return EC; diff --git a/lib/DebugInfo/CodeView/TypeTableBuilder.cpp b/lib/DebugInfo/CodeView/TypeTableBuilder.cpp index fcf27962102..1bd0b3f4382 100644 --- a/lib/DebugInfo/CodeView/TypeTableBuilder.cpp +++ b/lib/DebugInfo/CodeView/TypeTableBuilder.cpp @@ -72,13 +72,7 @@ TypeIndex TypeTableBuilder::writeKnownType(const PointerRecord &Record) { TypeRecordBuilder Builder(Record.getKind()); Builder.writeTypeIndex(Record.getReferentType()); - uint32_t flags = static_cast(Record.getOptions()) | - (Record.getSize() << PointerRecord::PointerSizeShift) | - (static_cast(Record.getMode()) - << PointerRecord::PointerModeShift) | - (static_cast(Record.getPointerKind()) - << PointerRecord::PointerKindShift); - Builder.writeUInt32(flags); + Builder.writeUInt32(Record.Attrs); if (Record.isPointerToMember()) { const MemberPointerInfo &M = Record.getMemberInfo(); diff --git a/lib/DebugInfo/MSF/StreamWriter.cpp b/lib/DebugInfo/MSF/StreamWriter.cpp index a91cffe840f..cdae7c5acc0 100644 --- a/lib/DebugInfo/MSF/StreamWriter.cpp +++ b/lib/DebugInfo/MSF/StreamWriter.cpp @@ -25,6 +25,8 @@ Error StreamWriter::writeBytes(ArrayRef Buffer) { return Error::success(); } +Error StreamWriter::writeInteger(uint8_t Int) { return writeObject(Int); } + Error StreamWriter::writeInteger(uint16_t Int) { return writeObject(support::ulittle16_t(Int)); } @@ -33,6 +35,24 @@ Error StreamWriter::writeInteger(uint32_t Int) { return writeObject(support::ulittle32_t(Int)); } +Error StreamWriter::writeInteger(uint64_t Int) { + return writeObject(support::ulittle64_t(Int)); +} + +Error StreamWriter::writeInteger(int8_t Int) { return writeObject(Int); } + +Error StreamWriter::writeInteger(int16_t Int) { + return writeObject(support::little16_t(Int)); +} + +Error StreamWriter::writeInteger(int32_t Int) { + return writeObject(support::little32_t(Int)); +} + +Error StreamWriter::writeInteger(int64_t Int) { + return writeObject(support::little64_t(Int)); +} + Error StreamWriter::writeZeroString(StringRef Str) { if (auto EC = writeFixedString(Str)) return EC; diff --git a/test/DebugInfo/PDB/pdbdump-yaml-types.test b/test/DebugInfo/PDB/pdbdump-yaml-types.test index 30f7585dc27..25895f3de2f 100644 --- a/test/DebugInfo/PDB/pdbdump-yaml-types.test +++ b/test/DebugInfo/PDB/pdbdump-yaml-types.test @@ -31,27 +31,27 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: apartment YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: single YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 3 YAML: Name: free YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 4 YAML: Name: neutral YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 5 YAML: Name: both YAML: - Kind: LF_ENUM @@ -69,18 +69,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::threadingAttribute' YAML: UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4100 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 4099 ] @@ -108,15 +103,11 @@ YAML: - Kind: LF_METHODLIST YAML: MethodOverloadList: YAML: Methods: YAML: - Type: 4103 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4104 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Kind: LF_FIELDLIST @@ -132,7 +123,7 @@ YAML: MethodList: 4105 YAML: Name: threadingAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4099 YAML: FieldOffset: 0 YAML: Name: value @@ -143,8 +134,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4106 YAML: Name: '__vc_attributes::threadingAttribute' YAML: UniqueName: '.?AUthreadingAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 4 @@ -152,17 +141,17 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 0 YAML: Name: native YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: com YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: managed YAML: - Kind: LF_ENUM @@ -180,18 +169,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::event_receiverAttribute' YAML: UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4110 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 4109, 48 ] @@ -232,21 +216,15 @@ YAML: - Kind: LF_METHODLIST YAML: MethodOverloadList: YAML: Methods: YAML: - Type: 4113 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4115 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4116 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Kind: LF_FIELDLIST @@ -262,13 +240,13 @@ YAML: MethodList: 4117 YAML: Name: event_receiverAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4109 YAML: FieldOffset: 0 YAML: Name: type YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 48 YAML: FieldOffset: 4 YAML: Name: layout_dependent @@ -279,8 +257,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4118 YAML: Name: '__vc_attributes::event_receiverAttribute' YAML: UniqueName: '.?AUevent_receiverAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 8 @@ -288,17 +264,17 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 0 YAML: Name: never YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: allowed YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: always YAML: - Kind: LF_ENUM @@ -316,18 +292,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::aggregatableAttribute' YAML: UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4122 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 4121 ] @@ -355,15 +326,11 @@ YAML: - Kind: LF_METHODLIST YAML: MethodOverloadList: YAML: Methods: YAML: - Type: 4125 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4126 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Kind: LF_FIELDLIST @@ -379,7 +346,7 @@ YAML: MethodList: 4127 YAML: Name: aggregatableAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4121 YAML: FieldOffset: 0 YAML: Name: type @@ -390,8 +357,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4128 YAML: Name: '__vc_attributes::aggregatableAttribute' YAML: UniqueName: '.?AUaggregatableAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 4 @@ -407,12 +372,12 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 0 YAML: Name: speed YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: size YAML: - Kind: LF_ENUM @@ -430,18 +395,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::event_sourceAttribute' YAML: UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4133 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 4130 ] @@ -469,15 +429,11 @@ YAML: - Kind: LF_METHODLIST YAML: MethodOverloadList: YAML: Methods: YAML: - Type: 4136 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4137 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Kind: LF_FIELDLIST @@ -497,19 +453,19 @@ YAML: MethodList: 4138 YAML: Name: event_sourceAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4130 YAML: FieldOffset: 0 YAML: Name: type YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4132 YAML: FieldOffset: 4 YAML: Name: optimize YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 48 YAML: FieldOffset: 8 YAML: Name: decorate @@ -520,8 +476,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4139 YAML: Name: '__vc_attributes::event_sourceAttribute' YAML: UniqueName: '.?AUevent_sourceAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 12 @@ -529,32 +483,32 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: dll YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: exe YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 3 YAML: Name: service YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 4 YAML: Name: unspecified YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: EXE YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 3 YAML: Name: SERVICE YAML: - Kind: LF_ENUM @@ -572,18 +526,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::moduleAttribute' YAML: UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4143 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_MODIFIER YAML: Modifier: YAML: ModifiedType: 112 @@ -591,10 +540,7 @@ YAML: Modifiers: [ None, Const ] YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4145 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None ] -YAML: Size: 4 +YAML: Attrs: 32778 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 4142, 4146, 4146, 4146, 116, 48, 4146, 116, @@ -636,21 +582,15 @@ YAML: - Kind: LF_METHODLIST YAML: MethodOverloadList: YAML: Methods: YAML: - Type: 4148 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4150 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Type: 4151 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: '' YAML: - Kind: LF_FIELDLIST @@ -666,91 +606,91 @@ YAML: MethodList: 4152 YAML: Name: moduleAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4142 YAML: FieldOffset: 0 YAML: Name: type YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 4 YAML: Name: name YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 8 YAML: Name: version YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 12 YAML: Name: uuid YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 116 YAML: FieldOffset: 16 YAML: Name: lcid YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 48 YAML: FieldOffset: 20 YAML: Name: control YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 24 YAML: Name: helpstring YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 116 YAML: FieldOffset: 28 YAML: Name: helpstringcontext YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 32 YAML: Name: helpstringdll YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 36 YAML: Name: helpfile YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 116 YAML: FieldOffset: 40 YAML: Name: helpcontext YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 48 YAML: FieldOffset: 44 YAML: Name: hidden YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 48 YAML: FieldOffset: 45 YAML: Name: restricted YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 48 YAML: Name: custom YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4146 YAML: FieldOffset: 52 YAML: Name: resource_name @@ -761,8 +701,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4153 YAML: Name: '__vc_attributes::moduleAttribute' YAML: UniqueName: '.?AUmoduleAttribute@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 56 @@ -770,152 +708,152 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 0 YAML: Name: eAnyUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: eCoClassUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: eCOMInterfaceUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 6 YAML: Name: eInterfaceUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 8 YAML: Name: eMemberUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 16 YAML: Name: eMethodUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 32 YAML: Name: eInterfaceMethodUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 64 YAML: Name: eInterfaceMemberUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 128 YAML: Name: eCoClassMemberUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 256 YAML: Name: eCoClassMethodUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 768 YAML: Name: eGlobalMethodUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1024 YAML: Name: eGlobalDataUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2048 YAML: Name: eClassUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 4096 YAML: Name: eInterfaceParameterUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 12288 YAML: Name: eMethodParameterUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 16384 YAML: Name: eIDLModuleUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: -32768 YAML: Name: eAnonymousUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 65536 YAML: Name: eTypedefUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 131072 YAML: Name: eUnionUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 262144 YAML: Name: eEnumUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 524288 YAML: Name: eDefineTagUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1048576 YAML: Name: eStructUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2097152 YAML: Name: eLocalUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 4194304 YAML: Name: ePropertyUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 8388608 YAML: Name: eEventUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 16777216 YAML: Name: eTemplateUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 16777216 YAML: Name: eModuleUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 33554432 YAML: Name: eIllegalUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 67108864 YAML: Name: eAsynchronousUsage YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 4161535 YAML: Name: eAnyIDLUsage YAML: - Kind: LF_ENUM @@ -933,18 +871,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::helper_attributes::usageAttribute' YAML: UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4157 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 117 ] @@ -967,14 +900,12 @@ YAML: Name: usage_e YAML: - Kind: LF_ONEMETHOD YAML: OneMethod: YAML: Type: 4160 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: usageAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 117 YAML: FieldOffset: 0 YAML: Name: value @@ -985,8 +916,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4161 YAML: Name: '__vc_attributes::helper_attributes::usageAttribute' YAML: UniqueName: '.?AUusageAttribute@helper_attributes@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 4 @@ -994,22 +923,22 @@ YAML: - Kind: LF_FIELDLIST YAML: FieldList: YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 0 YAML: Name: eBoolean YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 1 YAML: Name: eInteger YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 2 YAML: Name: eFloat YAML: - Kind: LF_ENUMERATE YAML: Enumerator: -YAML: Access: Public +YAML: Attrs: 3 YAML: Value: 3 YAML: Name: eDouble YAML: - Kind: LF_ENUM @@ -1027,18 +956,13 @@ YAML: Options: [ None, ForwardReference, HasUniqueName ] YAML: FieldList: 0 YAML: Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' YAML: UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 0 YAML: - Kind: LF_POINTER YAML: Pointer: YAML: ReferentType: 4165 -YAML: PtrKind: Near32 -YAML: Mode: Pointer -YAML: Options: [ None, Const ] -YAML: Size: 4 +YAML: Attrs: 33802 YAML: - Kind: LF_ARGLIST YAML: ArgList: YAML: ArgIndices: [ 4164 ] @@ -1061,14 +985,12 @@ YAML: Name: type_e YAML: - Kind: LF_ONEMETHOD YAML: OneMethod: YAML: Type: 4168 -YAML: Kind: Vanilla -YAML: Options: [ None ] -YAML: Access: Public +YAML: Attrs: 3 YAML: VFTableOffset: -1 YAML: Name: v1_alttypeAttribute YAML: - Kind: LF_MEMBER YAML: DataMember: -YAML: Access: Public +YAML: Attrs: 3 YAML: Type: 4164 YAML: FieldOffset: 0 YAML: Name: type @@ -1079,8 +1001,6 @@ YAML: Options: [ None, HasConstructorOrDestructor, ContainsNeste YAML: FieldList: 4169 YAML: Name: '__vc_attributes::helper_attributes::v1_alttypeAttribute' YAML: UniqueName: '.?AUv1_alttypeAttribute@helper_attributes@__vc_attributes@@' -YAML: Hfa: None -YAML: WinRTKind: None YAML: DerivationList: 0 YAML: VTableShape: 0 YAML: Size: 4 diff --git a/tools/llvm-pdbdump/YamlTypeDumper.cpp b/tools/llvm-pdbdump/YamlTypeDumper.cpp index d20e26d18d2..8fde16be1bc 100644 --- a/tools/llvm-pdbdump/YamlTypeDumper.cpp +++ b/tools/llvm-pdbdump/YamlTypeDumper.cpp @@ -300,8 +300,6 @@ void MappingTraits::mapping(IO &IO, ClassRecord &Class) { IO.mapRequired("FieldList", Class.FieldList); IO.mapRequired("Name", Class.Name); IO.mapRequired("UniqueName", Class.UniqueName); - IO.mapRequired("Hfa", Class.Hfa); - IO.mapRequired("WinRTKind", Class.WinRTKind); IO.mapRequired("DerivationList", Class.DerivationList); IO.mapRequired("VTableShape", Class.VTableShape); IO.mapRequired("Size", Class.Size); @@ -313,7 +311,6 @@ void MappingTraits::mapping(IO &IO, UnionRecord &Union) { IO.mapRequired("FieldList", Union.FieldList); IO.mapRequired("Name", Union.Name); IO.mapRequired("UniqueName", Union.UniqueName); - IO.mapRequired("Hfa", Union.Hfa); IO.mapRequired("Size", Union.Size); } @@ -337,7 +334,6 @@ void MappingTraits::mapping(IO &IO, VFTableRecord &VFT) { IO.mapRequired("CompleteClass", VFT.CompleteClass); IO.mapRequired("OverriddenVFTable", VFT.OverriddenVFTable); IO.mapRequired("VFPtrOffset", VFT.VFPtrOffset); - IO.mapRequired("Name", VFT.Name); IO.mapRequired("MethodNames", VFT.MethodNames); } @@ -387,10 +383,7 @@ void MappingTraits::mapping(IO &IO, TypeServer2Record &TS) { void MappingTraits::mapping(IO &IO, PointerRecord &Ptr) { IO.mapRequired("ReferentType", Ptr.ReferentType); - IO.mapRequired("PtrKind", Ptr.PtrKind); - IO.mapRequired("Mode", Ptr.Mode); - IO.mapRequired("Options", Ptr.Options); - IO.mapRequired("Size", Ptr.Size); + IO.mapRequired("Attrs", Ptr.Attrs); IO.mapOptional("MemberInfo", Ptr.MemberInfo); } @@ -442,9 +435,7 @@ void MappingTraits::mapping(IO &IO, void MappingTraits::mapping(IO &IO, OneMethodRecord &Method) { IO.mapRequired("Type", Method.Type); - IO.mapRequired("Kind", Method.Kind); - IO.mapRequired("Options", Method.Options); - IO.mapRequired("Access", Method.Access); + IO.mapRequired("Attrs", Method.Attrs.Attrs); IO.mapRequired("VFTableOffset", Method.VFTableOffset); IO.mapRequired("Name", Method.Name); } @@ -457,7 +448,7 @@ void MappingTraits::mapping( } void MappingTraits::mapping(IO &IO, DataMemberRecord &Field) { - IO.mapRequired("Access", Field.Access); + IO.mapRequired("Attrs", Field.Attrs.Attrs); IO.mapRequired("Type", Field.Type); IO.mapRequired("FieldOffset", Field.FieldOffset); IO.mapRequired("Name", Field.Name); @@ -465,7 +456,7 @@ void MappingTraits::mapping(IO &IO, DataMemberRecord &Field) { void MappingTraits::mapping( IO &IO, StaticDataMemberRecord &Field) { - IO.mapRequired("Access", Field.Access); + IO.mapRequired("Attrs", Field.Attrs.Attrs); IO.mapRequired("Type", Field.Type); IO.mapRequired("Name", Field.Name); } @@ -475,20 +466,20 @@ void MappingTraits::mapping(IO &IO, VFPtrRecord &VFTable) { } void MappingTraits::mapping(IO &IO, EnumeratorRecord &Enum) { - IO.mapRequired("Access", Enum.Access); + IO.mapRequired("Attrs", Enum.Attrs.Attrs); IO.mapRequired("Value", Enum.Value); IO.mapRequired("Name", Enum.Name); } void MappingTraits::mapping(IO &IO, BaseClassRecord &Base) { - IO.mapRequired("Access", Base.Access); + IO.mapRequired("Attrs", Base.Attrs.Attrs); IO.mapRequired("Type", Base.Type); IO.mapRequired("Offset", Base.Offset); } void MappingTraits::mapping( IO &IO, VirtualBaseClassRecord &Base) { - IO.mapRequired("Access", Base.Access); + IO.mapRequired("Attrs", Base.Attrs.Attrs); IO.mapRequired("BaseType", Base.BaseType); IO.mapRequired("VBPtrType", Base.VBPtrType); IO.mapRequired("VBPtrOffset", Base.VBPtrOffset); @@ -568,7 +559,10 @@ struct MappingContextTraits