<div dir="ltr">Thanks, I will have to take a look tomorrow as I'm gone for the day. Not sure how a undeclared identifier passed both MSVC and clang-cl, but I will check it out tomorrow. Thanks!</div><br><div class="gmail_quote"><div dir="ltr">On Tue, Aug 16, 2016 at 4:48 PM Justin Bogner <<a href="mailto:mail@justinbogner.com">mail@justinbogner.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Zachary Turner via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> writes:<br>
> Author: zturner<br>
> Date: Tue Aug 16 18:28:54 2016<br>
> New Revision: 278869<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=278869&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=278869&view=rev</a><br>
> Log:<br>
> Write the TPI stream from a PDB to Yaml.<br>
<br>
I reverted this in r278871, because it's hitting an error that I think<br>
will fire on most of the bots:<br>
<br>
.../llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp:36:17: error: use of undeclared identifier 'skipPadding'<br>
if (auto EC = skipPadding(Data))<br>
<br>
Less important, but I also got a pessimizing move warning:<br>
<br>
.../llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp:120:14: error: moving a local object in a return statement prevents copy elision [-Werror,-Wpessimizing-move]<br>
return std::move(EC);<br>
<br>
> Reviewed By: ruiu, rnk<br>
> Differential Revision: <a href="https://reviews.llvm.org/D23226" rel="noreferrer" target="_blank">https://reviews.llvm.org/D23226</a><br>
><br>
> Added:<br>
> llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test<br>
> llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp<br>
> llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h<br>
> Modified:<br>
> llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h<br>
> llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h<br>
> llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h<br>
> llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h<br>
> llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h<br>
> llvm/trunk/include/llvm/DebugInfo/MSF/StreamReader.h<br>
> llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp<br>
> llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp<br>
> llvm/trunk/lib/DebugInfo/CodeView/TypeDeserializer.cpp<br>
> llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp<br>
> llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp<br>
> llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp<br>
> llvm/trunk/test/DebugInfo/COFF/big-type.ll<br>
> llvm/trunk/test/DebugInfo/COFF/enum.ll<br>
> llvm/trunk/test/DebugInfo/COFF/inheritance.ll<br>
> llvm/trunk/test/DebugInfo/COFF/virtual-method-kinds.ll<br>
> llvm/trunk/test/DebugInfo/COFF/virtual-methods.ll<br>
> llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test<br>
> llvm/trunk/tools/llvm-pdbdump/CMakeLists.txt<br>
> llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp<br>
> llvm/trunk/tools/llvm-pdbdump/PdbYaml.h<br>
> llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp<br>
> llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h<br>
> llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp<br>
> llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h<br>
> URL:<br>
> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Tue Aug 16 18:28:54 2016<br>
> @@ -28,6 +28,8 @@ public:<br>
> /// Visits the type records in Data. Sets the error flag on parse failures.<br>
> Error visitTypeStream(const CVTypeArray &Types);<br>
><br>
> + Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList);<br>
> +<br>
> private:<br>
> /// The interface to the class that gets notified of each visitation.<br>
> TypeVisitorCallbacks &Callbacks;<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/EnumTables.h Tue Aug 16 18:28:54 2016<br>
> @@ -20,6 +20,7 @@<br>
> namespace llvm {<br>
> namespace codeview {<br>
> ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();<br>
> +ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();<br>
> ArrayRef<EnumEntry<uint16_t>> getRegisterNames();<br>
> ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();<br>
> ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h Tue Aug 16 18:28:54 2016<br>
> @@ -15,9 +15,9 @@<br>
><br>
> namespace llvm {<br>
> namespace codeview {<br>
> -class TypeDeserializerBase : public TypeVisitorCallbacks {<br>
> +class TypeDeserializer : public TypeVisitorCallbacks {<br>
> public:<br>
> - explicit TypeDeserializerBase(TypeVisitorCallbacks &Recipient)<br>
> + explicit TypeDeserializer(TypeVisitorCallbacks &Recipient)<br>
> : Recipient(Recipient) {}<br>
><br>
> Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {<br>
> @@ -62,39 +62,6 @@ private:<br>
> return Recipient.visitKnownRecord(CVR, Record);<br>
> }<br>
> };<br>
> -<br>
> -class TypeDeserializer : public TypeDeserializerBase {<br>
> -public:<br>
> - explicit TypeDeserializer(TypeVisitorCallbacks &Recipient)<br>
> - : TypeDeserializerBase(Recipient) {}<br>
> -<br>
> - /// FieldList records need special handling. For starters, they do not<br>
> - /// describe their own length, so a different extraction algorithm is<br>
> - /// necessary. Secondly, a single FieldList record will result in the<br>
> - /// deserialization of many records. So even though the top level visitor<br>
> - /// calls visitFieldBegin() on a single record, multiple records get visited<br>
> - /// through the callback interface.<br>
> - Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> - FieldListRecord &Record) override;<br>
> -<br>
> -private:<br>
> - template <typename T><br>
> - Error visitKnownMember(ArrayRef<uint8_t> &Data, TypeLeafKind Kind,<br>
> - T &Record) {<br>
> - ArrayRef<uint8_t> OldData = Data;<br>
> - if (auto EC = deserializeRecord(Data, Kind, Record))<br>
> - return EC;<br>
> - assert(Data.size() < OldData.size());<br>
> -<br>
> - CVRecord<TypeLeafKind> CVR;<br>
> - CVR.Length = OldData.size() - Data.size();<br>
> - CVR.Data = OldData.slice(0, CVR.Length);<br>
> - CVR.RawData = CVR.Data;<br>
> - return Recipient.visitKnownRecord(CVR, Record);<br>
> - }<br>
> -<br>
> - Error skipPadding(ArrayRef<uint8_t> &Data);<br>
> -};<br>
> }<br>
> }<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h Tue Aug 16 18:28:54 2016<br>
> @@ -87,6 +87,7 @@ private:<br>
><br>
> ScopedPrinter *W;<br>
><br>
> + bool IsInFieldList = false;<br>
> bool PrintRecordBytes = false;<br>
><br>
> /// Name of the current type. Only valid before visitTypeEnd.<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h Tue Aug 16 18:28:54 2016<br>
> @@ -12,6 +12,7 @@<br>
><br>
> #include "llvm/ADT/APSInt.h"<br>
> #include "llvm/ADT/ArrayRef.h"<br>
> +#include "llvm/ADT/Optional.h"<br>
> #include "llvm/ADT/StringRef.h"<br>
> #include "llvm/DebugInfo/CodeView/CVRecord.h"<br>
> #include "llvm/DebugInfo/CodeView/CodeView.h"<br>
> @@ -27,6 +28,9 @@ using llvm::support::little32_t;<br>
> using llvm::support::ulittle16_t;<br>
> using llvm::support::ulittle32_t;<br>
><br>
> +typedef CVRecord<TypeLeafKind> CVType;<br>
> +typedef msf::VarStreamArray<CVType> CVTypeArray;<br>
> +<br>
> /// Equvalent to CV_fldattr_t in cvinfo.h.<br>
> struct MemberAttributes {<br>
> ulittle16_t Attrs;<br>
> @@ -90,18 +94,19 @@ public:<br>
> return Representation;<br>
> }<br>
><br>
> + TypeIndex ContainingType;<br>
> + PointerToMemberRepresentation Representation;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> TypeIndex ClassType;<br>
> ulittle16_t Representation; // PointerToMemberRepresentation<br>
> };<br>
> -<br>
> - TypeIndex ContainingType;<br>
> - PointerToMemberRepresentation Representation;<br>
> };<br>
><br>
> class TypeRecord {<br>
> protected:<br>
> + TypeRecord() {}<br>
> explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}<br>
><br>
> public:<br>
> @@ -129,14 +134,14 @@ public:<br>
> TypeIndex getModifiedType() const { return ModifiedType; }<br>
> ModifierOptions getModifiers() const { return Modifiers; }<br>
><br>
> + TypeIndex ModifiedType;<br>
> + ModifierOptions Modifiers;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> TypeIndex ModifiedType;<br>
> ulittle16_t Modifiers; // ModifierOptions<br>
> };<br>
> -<br>
> - TypeIndex ModifiedType;<br>
> - ModifierOptions Modifiers;<br>
> };<br>
><br>
> // LF_PROCEDURE<br>
> @@ -165,6 +170,12 @@ public:<br>
> uint16_t getParameterCount() const { return ParameterCount; }<br>
> TypeIndex getArgumentList() const { return ArgumentList; }<br>
><br>
> + TypeIndex ReturnType;<br>
> + CallingConvention CallConv;<br>
> + FunctionOptions Options;<br>
> + uint16_t ParameterCount;<br>
> + TypeIndex ArgumentList;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> TypeIndex ReturnType;<br>
> @@ -173,12 +184,6 @@ private:<br>
> ulittle16_t NumParameters;<br>
> TypeIndex ArgListType;<br>
> };<br>
> -<br>
> - TypeIndex ReturnType;<br>
> - CallingConvention CallConv;<br>
> - FunctionOptions Options;<br>
> - uint16_t ParameterCount;<br>
> - TypeIndex ArgumentList;<br>
> };<br>
><br>
> // LF_MFUNCTION<br>
> @@ -212,6 +217,15 @@ public:<br>
> TypeIndex getArgumentList() const { return ArgumentList; }<br>
> int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }<br>
><br>
> + TypeIndex ReturnType;<br>
> + TypeIndex ClassType;<br>
> + TypeIndex ThisType;<br>
> + CallingConvention CallConv;<br>
> + FunctionOptions Options;<br>
> + uint16_t ParameterCount;<br>
> + TypeIndex ArgumentList;<br>
> + int32_t ThisPointerAdjustment;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> TypeIndex ReturnType;<br>
> @@ -223,15 +237,6 @@ private:<br>
> TypeIndex ArgListType;<br>
> little32_t ThisAdjustment;<br>
> };<br>
> -<br>
> - TypeIndex ReturnType;<br>
> - TypeIndex ClassType;<br>
> - TypeIndex ThisType;<br>
> - CallingConvention CallConv;<br>
> - FunctionOptions Options;<br>
> - uint16_t ParameterCount;<br>
> - TypeIndex ArgumentList;<br>
> - int32_t ThisPointerAdjustment;<br>
> };<br>
><br>
> // LF_MFUNC_ID<br>
> @@ -252,6 +257,9 @@ public:<br>
> TypeIndex getClassType() const { return ClassType; }<br>
> TypeIndex getFunctionType() const { return FunctionType; }<br>
> StringRef getName() const { return Name; }<br>
> + TypeIndex ClassType;<br>
> + TypeIndex FunctionType;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -259,9 +267,6 @@ private:<br>
> TypeIndex FunctionType;<br>
> // Name: The null-terminated name follows.<br>
> };<br>
> - TypeIndex ClassType;<br>
> - TypeIndex FunctionType;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_ARGLIST, LF_SUBSTR_LIST<br>
> @@ -283,13 +288,13 @@ public:<br>
><br>
> static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }<br>
><br>
> + std::vector<TypeIndex> StringIndices;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> ulittle32_t NumArgs; // Number of arguments<br>
> // ArgTypes[]: Type indicies of arguments<br>
> };<br>
> -<br>
> - std::vector<TypeIndex> StringIndices;<br>
> };<br>
><br>
> // LF_POINTER<br>
> @@ -308,8 +313,8 @@ public:<br>
><br>
> PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,<br>
> PointerOptions Options, uint8_t Size)<br>
> - : PointerRecord(ReferentType, Kind, Mode, Options, Size,<br>
> - MemberPointerInfo()) {}<br>
> + : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),<br>
> + PtrKind(Kind), Mode(Mode), Options(Options), Size(Size) {}<br>
><br>
> PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,<br>
> PointerOptions Options, uint8_t Size,<br>
> @@ -330,7 +335,7 @@ public:<br>
> PointerMode getMode() const { return Mode; }<br>
> PointerOptions getOptions() const { return Options; }<br>
> uint8_t getSize() const { return Size; }<br>
> - MemberPointerInfo getMemberInfo() const { return MemberInfo; }<br>
> + MemberPointerInfo getMemberInfo() const { return *MemberInfo; }<br>
><br>
> bool isPointerToMember() const {<br>
> return Mode == PointerMode::PointerToDataMember ||<br>
> @@ -349,6 +354,13 @@ public:<br>
> return !!(uint32_t(Options) & uint32_t(PointerOptions::Unaligned));<br>
> }<br>
><br>
> + TypeIndex ReferentType;<br>
> + PointerKind PtrKind;<br>
> + PointerMode Mode;<br>
> + PointerOptions Options;<br>
> + uint8_t Size;<br>
> + Optional<MemberPointerInfo> MemberInfo;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> TypeIndex PointeeType;<br>
> @@ -379,13 +391,6 @@ private:<br>
> return isPointerToMemberFunction() || isPointerToDataMember();<br>
> }<br>
> };<br>
> -<br>
> - TypeIndex ReferentType;<br>
> - PointerKind PtrKind;<br>
> - PointerMode Mode;<br>
> - PointerOptions Options;<br>
> - uint8_t Size;<br>
> - MemberPointerInfo MemberInfo;<br>
> };<br>
><br>
> // LF_NESTTYPE<br>
> @@ -405,23 +410,23 @@ public:<br>
> TypeIndex getNestedType() const { return Type; }<br>
> StringRef getName() const { return Name; }<br>
><br>
> + TypeIndex Type;<br>
> + StringRef Name;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> ulittle16_t Pad0; // Should be zero<br>
> TypeIndex Type; // Type index of nested type<br>
> // Name: Null-terminated string<br>
> };<br>
> -<br>
> - TypeIndex Type;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_FIELDLIST<br>
> class FieldListRecord : public TypeRecord {<br>
> public:<br>
> explicit FieldListRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}<br>
> - FieldListRecord(ArrayRef<uint8_t> ListData)<br>
> - : TypeRecord(TypeRecordKind::FieldList), ListData(ListData) {}<br>
> + explicit FieldListRecord(ArrayRef<uint8_t> Data)<br>
> + : TypeRecord(TypeRecordKind::FieldList), Data(Data) {}<br>
><br>
> /// Rewrite member type indices with IndexMap. Returns false if a type index<br>
> /// is not in the map.<br>
> @@ -430,10 +435,7 @@ public:<br>
> static Expected<FieldListRecord> deserialize(TypeRecordKind Kind,<br>
> ArrayRef<uint8_t> &Data);<br>
><br>
> - ArrayRef<uint8_t> getFieldListData() const { return ListData; }<br>
> -<br>
> -private:<br>
> - ArrayRef<uint8_t> ListData;<br>
> + ArrayRef<uint8_t> Data;<br>
> };<br>
><br>
> // LF_ARRAY<br>
> @@ -457,6 +459,11 @@ public:<br>
> uint64_t getSize() const { return Size; }<br>
> llvm::StringRef getName() const { return Name; }<br>
><br>
> + TypeIndex ElementType;<br>
> + TypeIndex IndexType;<br>
> + uint64_t Size;<br>
> + llvm::StringRef Name;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> TypeIndex ElementType;<br>
> @@ -464,11 +471,6 @@ private:<br>
> // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!<br>
> // Name: The null-terminated name follows.<br>
> };<br>
> -<br>
> - TypeIndex ElementType;<br>
> - TypeIndex IndexType;<br>
> - uint64_t Size;<br>
> - llvm::StringRef Name;<br>
> };<br>
><br>
> class TagRecord : public TypeRecord {<br>
> @@ -495,7 +497,6 @@ public:<br>
> StringRef getName() const { return Name; }<br>
> StringRef getUniqueName() const { return UniqueName; }<br>
><br>
> -private:<br>
> uint16_t MemberCount;<br>
> ClassOptions Options;<br>
> TypeIndex FieldList;<br>
> @@ -528,6 +529,12 @@ public:<br>
> TypeIndex getVTableShape() const { return VTableShape; }<br>
> uint64_t getSize() const { return Size; }<br>
><br>
> + HfaKind Hfa;<br>
> + WindowsRTClassKind WinRTKind;<br>
> + TypeIndex DerivationList;<br>
> + TypeIndex VTableShape;<br>
> + uint64_t Size;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> ulittle16_t MemberCount; // Number of members in FieldList.<br>
> @@ -543,12 +550,6 @@ private:<br>
> return Properties & uint16_t(ClassOptions::HasUniqueName);<br>
> }<br>
> };<br>
> -<br>
> - HfaKind Hfa;<br>
> - WindowsRTClassKind WinRTKind;<br>
> - TypeIndex DerivationList;<br>
> - TypeIndex VTableShape;<br>
> - uint64_t Size;<br>
> };<br>
><br>
> // LF_UNION<br>
> @@ -567,6 +568,9 @@ struct UnionRecord : public TagRecord {<br>
> HfaKind getHfa() const { return Hfa; }<br>
> uint64_t getSize() const { return Size; }<br>
><br>
> + HfaKind Hfa;<br>
> + uint64_t Size;<br>
> +<br>
> private:<br>
> struct Layout {<br>
> ulittle16_t MemberCount; // Number of members in FieldList.<br>
> @@ -580,9 +584,6 @@ private:<br>
> return Properties & uint16_t(ClassOptions::HasUniqueName);<br>
> }<br>
> };<br>
> -<br>
> - HfaKind Hfa;<br>
> - uint64_t Size;<br>
> };<br>
><br>
> // LF_ENUM<br>
> @@ -602,6 +603,7 @@ public:<br>
> ArrayRef<uint8_t> &Data);<br>
><br>
> TypeIndex getUnderlyingType() const { return UnderlyingType; }<br>
> + TypeIndex UnderlyingType;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -616,7 +618,6 @@ private:<br>
> }<br>
> };<br>
><br>
> - TypeIndex UnderlyingType;<br>
> };<br>
><br>
> // LF_BITFIELD<br>
> @@ -637,6 +638,9 @@ public:<br>
> TypeIndex getType() const { return Type; }<br>
> uint8_t getBitOffset() const { return BitOffset; }<br>
> uint8_t getBitSize() const { return BitSize; }<br>
> + TypeIndex Type;<br>
> + uint8_t BitSize;<br>
> + uint8_t BitOffset;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -645,9 +649,6 @@ private:<br>
> uint8_t BitOffset;<br>
> };<br>
><br>
> - TypeIndex Type;<br>
> - uint8_t BitSize;<br>
> - uint8_t BitOffset;<br>
> };<br>
><br>
> // LF_VTSHAPE<br>
> @@ -672,6 +673,8 @@ public:<br>
> return Slots;<br>
> }<br>
> uint32_t getEntryCount() const { return getSlots().size(); }<br>
> + ArrayRef<VFTableSlotKind> SlotsRef;<br>
> + std::vector<VFTableSlotKind> Slots;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -682,9 +685,6 @@ private:<br>
> // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e.<br>
> };<br>
><br>
> -private:<br>
> - ArrayRef<VFTableSlotKind> SlotsRef;<br>
> - std::vector<VFTableSlotKind> Slots;<br>
> };<br>
><br>
> // LF_TYPESERVER2<br>
> @@ -707,6 +707,9 @@ public:<br>
> uint32_t getAge() const { return Age; }<br>
><br>
> StringRef getName() const { return Name; }<br>
> + StringRef Guid;<br>
> + uint32_t Age;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -714,10 +717,6 @@ private:<br>
> ulittle32_t Age;<br>
> // Name: Name of the PDB as a null-terminated string<br>
> };<br>
> -<br>
> - StringRef Guid;<br>
> - uint32_t Age;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_STRING_ID<br>
> @@ -737,15 +736,14 @@ public:<br>
> TypeIndex getId() const { return Id; }<br>
><br>
> StringRef getString() const { return String; }<br>
> + TypeIndex Id;<br>
> + StringRef String;<br>
><br>
> private:<br>
> struct Layout {<br>
> TypeIndex id;<br>
> // Name: Name of the PDB as a null-terminated string<br>
> };<br>
> -<br>
> - TypeIndex Id;<br>
> - StringRef String;<br>
> };<br>
><br>
> // LF_FUNC_ID<br>
> @@ -768,6 +766,9 @@ public:<br>
> TypeIndex getFunctionType() const { return FunctionType; }<br>
><br>
> StringRef getName() const { return Name; }<br>
> + TypeIndex ParentScope;<br>
> + TypeIndex FunctionType;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -776,9 +777,6 @@ private:<br>
> // Name: The null-terminated name follows.<br>
> };<br>
><br>
> - TypeIndex ParentScope;<br>
> - TypeIndex FunctionType;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_UDT_SRC_LINE<br>
> @@ -799,6 +797,9 @@ public:<br>
> TypeIndex getUDT() const { return UDT; }<br>
> TypeIndex getSourceFile() const { return SourceFile; }<br>
> uint32_t getLineNumber() const { return LineNumber; }<br>
> + TypeIndex UDT;<br>
> + TypeIndex SourceFile;<br>
> + uint32_t LineNumber;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -807,9 +808,6 @@ private:<br>
> ulittle32_t LineNumber;<br>
> };<br>
><br>
> - TypeIndex UDT;<br>
> - TypeIndex SourceFile;<br>
> - uint32_t LineNumber;<br>
> };<br>
><br>
> // LF_UDT_MOD_SRC_LINE<br>
> @@ -836,6 +834,10 @@ public:<br>
> TypeIndex getSourceFile() const { return SourceFile; }<br>
> uint32_t getLineNumber() const { return LineNumber; }<br>
> uint16_t getModule() const { return Module; }<br>
> + TypeIndex UDT;<br>
> + TypeIndex SourceFile;<br>
> + uint32_t LineNumber;<br>
> + uint16_t Module;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -845,10 +847,6 @@ private:<br>
> ulittle16_t Module; // Module that contributes this UDT definition<br>
> };<br>
><br>
> - TypeIndex UDT;<br>
> - TypeIndex SourceFile;<br>
> - uint32_t LineNumber;<br>
> - uint16_t Module;<br>
> };<br>
><br>
> // LF_BUILDINFO<br>
> @@ -867,13 +865,13 @@ public:<br>
> ArrayRef<uint8_t> &Data);<br>
><br>
> ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }<br>
> + SmallVector<TypeIndex, 4> ArgIndices;<br>
><br>
> private:<br>
> struct Layout {<br>
> ulittle16_t NumArgs; // Number of arguments<br>
> // ArgTypes[]: Type indicies of arguments<br>
> };<br>
> - SmallVector<TypeIndex, 4> ArgIndices;<br>
> };<br>
><br>
> // LF_VFTABLE<br>
> @@ -909,6 +907,12 @@ public:<br>
> return MethodNamesRef;<br>
> return MethodNames;<br>
> }<br>
> + TypeIndex CompleteClass;<br>
> + TypeIndex OverriddenVFTable;<br>
> + ulittle32_t VFPtrOffset;<br>
> + StringRef Name;<br>
> + ArrayRef<StringRef> MethodNamesRef;<br>
> + std::vector<StringRef> MethodNames;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -920,17 +924,12 @@ private:<br>
> // names.<br>
> };<br>
><br>
> - TypeIndex CompleteClass;<br>
> - TypeIndex OverriddenVFTable;<br>
> - ulittle32_t VFPtrOffset;<br>
> - StringRef Name;<br>
> - ArrayRef<StringRef> MethodNamesRef;<br>
> - std::vector<StringRef> MethodNames;<br>
> };<br>
><br>
> // LF_ONEMETHOD<br>
> class OneMethodRecord : public TypeRecord {<br>
> public:<br>
> + OneMethodRecord() : TypeRecord(TypeRecordKind::OneMethod) {}<br>
> explicit OneMethodRecord(TypeRecordKind Kind) : TypeRecord(Kind) {}<br>
> OneMethodRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options,<br>
> MemberAccess Access, int32_t VFTableOffset, StringRef Name)<br>
> @@ -956,6 +955,12 @@ public:<br>
> return Kind == MethodKind::IntroducingVirtual ||<br>
> Kind == MethodKind::PureIntroducingVirtual;<br>
> }<br>
> + TypeIndex Type;<br>
> + MethodKind Kind;<br>
> + MethodOptions Options;<br>
> + MemberAccess Access;<br>
> + int32_t VFTableOffset;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -966,12 +971,6 @@ private:<br>
> // Name: Null-terminated string<br>
> };<br>
><br>
> - TypeIndex Type;<br>
> - MethodKind Kind;<br>
> - MethodOptions Options;<br>
> - MemberAccess Access;<br>
> - int32_t VFTableOffset;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_METHODLIST<br>
> @@ -989,6 +988,7 @@ public:<br>
> deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data);<br>
><br>
> ArrayRef<OneMethodRecord> getMethods() const { return Methods; }<br>
> + std::vector<OneMethodRecord> Methods;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1000,7 +1000,6 @@ private:<br>
> // VFTableOffset: int32_t offset in vftable<br>
> };<br>
><br>
> - std::vector<OneMethodRecord> Methods;<br>
> };<br>
><br>
> /// For method overload sets. LF_METHOD<br>
> @@ -1022,6 +1021,9 @@ public:<br>
> uint16_t getNumOverloads() const { return NumOverloads; }<br>
> TypeIndex getMethodList() const { return MethodList; }<br>
> StringRef getName() const { return Name; }<br>
> + uint16_t NumOverloads;<br>
> + TypeIndex MethodList;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1030,9 +1032,6 @@ private:<br>
> // Name: Null-terminated string<br>
> };<br>
><br>
> - uint16_t NumOverloads;<br>
> - TypeIndex MethodList;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_MEMBER<br>
> @@ -1055,6 +1054,10 @@ public:<br>
> TypeIndex getType() const { return Type; }<br>
> uint64_t getFieldOffset() const { return FieldOffset; }<br>
> StringRef getName() const { return Name; }<br>
> + MemberAccess Access;<br>
> + TypeIndex Type;<br>
> + uint64_t FieldOffset;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1064,10 +1067,6 @@ private:<br>
> // Name: Null-terminated string<br>
> };<br>
><br>
> - MemberAccess Access;<br>
> - TypeIndex Type;<br>
> - uint64_t FieldOffset;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_STMEMBER<br>
> @@ -1088,6 +1087,9 @@ public:<br>
> MemberAccess getAccess() const { return Access; }<br>
> TypeIndex getType() const { return Type; }<br>
> StringRef getName() const { return Name; }<br>
> + MemberAccess Access;<br>
> + TypeIndex Type;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1096,9 +1098,6 @@ private:<br>
> // Name: Null-terminated string<br>
> };<br>
><br>
> - MemberAccess Access;<br>
> - TypeIndex Type;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_ENUMERATE<br>
> @@ -1119,6 +1118,9 @@ public:<br>
> MemberAccess getAccess() const { return Access; }<br>
> APSInt getValue() const { return Value; }<br>
> StringRef getName() const { return Name; }<br>
> + MemberAccess Access;<br>
> + APSInt Value;<br>
> + StringRef Name;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1127,9 +1129,6 @@ private:<br>
> // Name: Null-terminated string<br>
> };<br>
><br>
> - MemberAccess Access;<br>
> - APSInt Value;<br>
> - StringRef Name;<br>
> };<br>
><br>
> // LF_VFUNCTAB<br>
> @@ -1147,13 +1146,13 @@ public:<br>
> ArrayRef<uint8_t> &Data);<br>
><br>
> TypeIndex getType() const { return Type; }<br>
> + TypeIndex Type;<br>
><br>
> private:<br>
> struct Layout {<br>
> ulittle16_t Pad0;<br>
> TypeIndex Type; // Type of vfptr<br>
> };<br>
> - TypeIndex Type;<br>
> };<br>
><br>
> // LF_BCLASS, LF_BINTERFACE<br>
> @@ -1174,6 +1173,9 @@ public:<br>
> MemberAccess getAccess() const { return Access; }<br>
> TypeIndex getBaseType() const { return Type; }<br>
> uint64_t getBaseOffset() const { return Offset; }<br>
> + MemberAccess Access;<br>
> + TypeIndex Type;<br>
> + uint64_t Offset;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1181,9 +1183,6 @@ private:<br>
> TypeIndex BaseType; // Base class type<br>
> // BaseOffset: LF_NUMERIC encoded byte offset of base from derived.<br>
> };<br>
> - MemberAccess Access;<br>
> - TypeIndex Type;<br>
> - uint64_t Offset;<br>
> };<br>
><br>
> // LF_VBCLASS, LF_IVBCLASS<br>
> @@ -1208,6 +1207,11 @@ public:<br>
> TypeIndex getVBPtrType() const { return VBPtrType; }<br>
> uint64_t getVBPtrOffset() const { return VBPtrOffset; }<br>
> uint64_t getVTableIndex() const { return VTableIndex; }<br>
> + MemberAccess Access;<br>
> + TypeIndex BaseType;<br>
> + TypeIndex VBPtrType;<br>
> + uint64_t VBPtrOffset;<br>
> + uint64_t VTableIndex;<br>
><br>
> private:<br>
> struct Layout {<br>
> @@ -1217,11 +1221,6 @@ private:<br>
> // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC.<br>
> // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC.<br>
> };<br>
> - MemberAccess Access;<br>
> - TypeIndex BaseType;<br>
> - TypeIndex VBPtrType;<br>
> - uint64_t VBPtrOffset;<br>
> - uint64_t VTableIndex;<br>
> };<br>
><br>
> /// LF_INDEX - Used to chain two large LF_FIELDLIST or LF_METHODLIST records<br>
> @@ -1239,17 +1238,15 @@ public:<br>
><br>
> static Expected<ListContinuationRecord> deserialize(TypeRecordKind Kind,<br>
> ArrayRef<uint8_t> &Data);<br>
> + TypeIndex ContinuationIndex;<br>
><br>
> private:<br>
> struct Layout {<br>
> ulittle16_t Pad0;<br>
> TypeIndex ContinuationIndex;<br>
> };<br>
> - TypeIndex ContinuationIndex;<br>
> };<br>
><br>
> -typedef CVRecord<TypeLeafKind> CVType;<br>
> -typedef msf::VarStreamArray<CVType> CVTypeArray;<br>
> }<br>
> }<br>
><br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo/MSF/StreamReader.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/StreamReader.h?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/StreamReader.h?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo/MSF/StreamReader.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo/MSF/StreamReader.h Tue Aug 16 18:28:54 2016<br>
> @@ -95,6 +95,7 @@ public:<br>
> return Error::success();<br>
> }<br>
><br>
> + bool empty() const { return bytesRemaining() == 0; }<br>
> void setOffset(uint32_t Off) { Offset = Off; }<br>
> uint32_t getOffset() const { return Offset; }<br>
> uint32_t getLength() const { return Stream.getLength(); }<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp Tue Aug 16 18:28:54 2016<br>
> @@ -15,6 +15,52 @@<br>
> using namespace llvm;<br>
> using namespace llvm::codeview;<br>
><br>
> +template <typename T><br>
> +static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {<br>
> + if (Data.size() < sizeof(*Res))<br>
> + return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);<br>
> + Res = reinterpret_cast<const T *>(Data.data());<br>
> + Data = Data.drop_front(sizeof(*Res));<br>
> + return Error::success();<br>
> +}<br>
> +<br>
> +template <typename T><br>
> +static Expected<CVType> deserializeMemberRecord(ArrayRef<uint8_t> &Data,<br>
> + TypeLeafKind Kind) {<br>
> + ArrayRef<uint8_t> OldData = Data;<br>
> + TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);<br>
> + auto ExpectedRecord = T::deserialize(RK, Data);<br>
> + if (!ExpectedRecord)<br>
> + return ExpectedRecord.takeError();<br>
> + assert(Data.size() < OldData.size());<br>
> + if (auto EC = skipPadding(Data))<br>
> + return std::move(EC);<br>
> +<br>
> + CVType CVR;<br>
> + CVR.Type = Kind;<br>
> + CVR.Length = OldData.size() - Data.size();<br>
> + CVR.Data = OldData.slice(0, CVR.Length);<br>
> + CVR.RawData = CVR.Data;<br>
> + return CVR;<br>
> +}<br>
> +<br>
> +static Error skipPadding(ArrayRef<uint8_t> &Data) {<br>
> + if (Data.empty())<br>
> + return Error::success();<br>
> + uint8_t Leaf = Data.front();<br>
> + if (Leaf < LF_PAD0)<br>
> + return Error::success();<br>
> + // Leaf is greater than 0xf0. We should advance by the number of bytes in<br>
> + // the low 4 bits.<br>
> + unsigned BytesToAdvance = Leaf & 0x0F;<br>
> + if (Data.size() < BytesToAdvance) {<br>
> + return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record,<br>
> + "Invalid padding bytes!");<br>
> + }<br>
> + Data = Data.drop_front(BytesToAdvance);<br>
> + return Error::success();<br>
> +}<br>
> +<br>
> CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)<br>
> : Callbacks(Callbacks) {}<br>
><br>
> @@ -45,7 +91,10 @@ Error CVTypeVisitor::visitTypeRecord(con<br>
> }<br>
> #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \<br>
> TYPE_RECORD(EnumVal, EnumVal, AliasName)<br>
> -#define MEMBER_RECORD(EnumName, EnumVal, Name)<br>
> +#define MEMBER_RECORD(EnumName, EnumVal, Name) \<br>
> + TYPE_RECORD(EnumName, EnumVal, Name)<br>
> +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \<br>
> + MEMBER_RECORD(EnumName, EnumVal, AliasName)<br>
> #include "llvm/DebugInfo/CodeView/TypeRecords.def"<br>
> }<br>
><br>
> @@ -63,3 +112,39 @@ Error CVTypeVisitor::visitTypeStream(con<br>
> }<br>
> return Error::success();<br>
> }<br>
> +<br>
> +Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {<br>
> + while (!Data.empty()) {<br>
> + const support::ulittle16_t *LeafValue;<br>
> + if (auto EC = takeObject(Data, LeafValue))<br>
> + return std::move(EC);<br>
> +<br>
> + TypeLeafKind Leaf = static_cast<TypeLeafKind>(uint16_t(*LeafValue));<br>
> + CVType Record;<br>
> + switch (Leaf) {<br>
> + default:<br>
> + // Field list records do not describe their own length, so we cannot<br>
> + // continue parsing past a type that we don't know how to deserialize.<br>
> + return llvm::make_error<CodeViewError>(<br>
> + cv_error_code::unknown_member_record);<br>
> +#define MEMBER_RECORD(EnumName, EnumVal, Name) \<br>
> + case EnumName: { \<br>
> + auto ExpectedRecord = deserializeMemberRecord<Name##Record>(Data, Leaf); \<br>
> + if (!ExpectedRecord) \<br>
> + return ExpectedRecord.takeError(); \<br>
> + auto &Record = *ExpectedRecord; \<br>
> + if (auto EC = Callbacks.visitTypeBegin(Record)) \<br>
> + return EC; \<br>
> + if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \<br>
> + return EC; \<br>
> + if (auto EC = Callbacks.visitTypeEnd(Record)) \<br>
> + return EC; \<br>
> + break; \<br>
> + }<br>
> +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \<br>
> + MEMBER_RECORD(EnumVal, EnumVal, AliasName)<br>
> +#include "llvm/DebugInfo/CodeView/TypeRecords.def"<br>
> + }<br>
> + }<br>
> + return Error::success();<br>
> +}<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/EnumTables.cpp Tue Aug 16 18:28:54 2016<br>
> @@ -24,6 +24,12 @@ static const EnumEntry<SymbolKind> Symbo<br>
> #undef CV_SYMBOL<br>
> };<br>
><br>
> +static const EnumEntry<TypeLeafKind> TypeLeafNames[] = {<br>
> +#define CV_TYPE(name, val) {#name, name},<br>
> +#include "llvm/DebugInfo/CodeView/TypeRecords.def"<br>
> +#undef CV_TYPE<br>
> +};<br>
> +<br>
> static const EnumEntry<uint16_t> RegisterNames[] = {<br>
> CV_ENUM_CLASS_ENT(RegisterId, Unknown),<br>
> CV_ENUM_CLASS_ENT(RegisterId, VFrame),<br>
> @@ -324,6 +330,10 @@ ArrayRef<EnumEntry<SymbolKind>> getSymbo<br>
> return makeArrayRef(SymbolTypeNames);<br>
> }<br>
><br>
> +ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {<br>
> + return makeArrayRef(TypeLeafNames);<br>
> +}<br>
> +<br>
> ArrayRef<EnumEntry<uint16_t>> getRegisterNames() {<br>
> return makeArrayRef(RegisterNames);<br>
> }<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDeserializer.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDeserializer.cpp?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDeserializer.cpp?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/TypeDeserializer.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeDeserializer.cpp Tue Aug 16 18:28:54 2016<br>
> @@ -11,71 +11,3 @@<br>
><br>
> using namespace llvm;<br>
> using namespace llvm::codeview;<br>
> -<br>
> -template <typename T><br>
> -static Error takeObject(ArrayRef<uint8_t> &Data, const T *&Res) {<br>
> - if (Data.size() < sizeof(*Res))<br>
> - return llvm::make_error<CodeViewError>(cv_error_code::insufficient_buffer);<br>
> - Res = reinterpret_cast<const T *>(Data.data());<br>
> - Data = Data.drop_front(sizeof(*Res));<br>
> - return Error::success();<br>
> -}<br>
> -<br>
> -Error TypeDeserializer::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> - FieldListRecord &Record) {<br>
> - ArrayRef<uint8_t> FieldListRecordData = CVR.Data;<br>
> - auto ExpectedRecord = FieldListRecord::deserialize(TypeRecordKind::FieldList,<br>
> - FieldListRecordData);<br>
> - if (!ExpectedRecord)<br>
> - return ExpectedRecord.takeError();<br>
> -<br>
> - Record = *ExpectedRecord;<br>
> - ArrayRef<uint8_t> MemberData = Record.getFieldListData();<br>
> -<br>
> - while (!MemberData.empty()) {<br>
> - const ulittle16_t *LeafPtr;<br>
> - if (auto EC = takeObject(MemberData, LeafPtr))<br>
> - return EC;<br>
> - TypeLeafKind Leaf = TypeLeafKind(unsigned(*LeafPtr));<br>
> - switch (Leaf) {<br>
> - default:<br>
> - // Field list records do not describe their own length, so we cannot<br>
> - // continue parsing past a type that we don't know how to deserialize.<br>
> - if (auto EC = Recipient.visitUnknownMember(CVR))<br>
> - return EC;<br>
> - return llvm::make_error<CodeViewError>(<br>
> - cv_error_code::unknown_member_record);<br>
> -#define MEMBER_RECORD(EnumName, EnumVal, Name) \<br>
> - case EnumName: { \<br>
> - TypeRecordKind RK = static_cast<TypeRecordKind>(Leaf); \<br>
> - Name##Record Member(RK); \<br>
> - if (auto EC = visitKnownMember(MemberData, Leaf, Member)) \<br>
> - return EC; \<br>
> - break; \<br>
> - }<br>
> -#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \<br>
> - MEMBER_RECORD(EnumVal, EnumVal, AliasName)<br>
> -#include "llvm/DebugInfo/CodeView/TypeRecords.def"<br>
> - }<br>
> - if (auto EC = skipPadding(MemberData))<br>
> - return EC;<br>
> - }<br>
> - return Error::success();<br>
> -}<br>
> -<br>
> -Error TypeDeserializer::skipPadding(ArrayRef<uint8_t> &Data) {<br>
> - if (Data.empty())<br>
> - return Error::success();<br>
> - uint8_t Leaf = Data.front();<br>
> - if (Leaf < LF_PAD0)<br>
> - return Error::success();<br>
> - // Leaf is greater than 0xf0. We should advance by the number of bytes in<br>
> - // the low 4 bits.<br>
> - unsigned BytesToAdvance = Leaf & 0x0F;<br>
> - if (Data.size() < BytesToAdvance) {<br>
> - return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record,<br>
> - "Invalid padding bytes!");<br>
> - }<br>
> - Data = Data.drop_front(BytesToAdvance);<br>
> - return Error::success();<br>
> -}<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Tue Aug 16 18:28:54 2016<br>
> @@ -206,21 +206,38 @@ Error CVTypeDumper::visitTypeBegin(const<br>
> // Reset Name to the empty string. If the visitor sets it, we know it.<br>
> Name = "";<br>
><br>
> - W->startLine() << getLeafTypeName(Record.Type) << " ("<br>
> - << HexNumber(getNextTypeIndex()) << ") {\n";<br>
> + W->startLine() << getLeafTypeName(Record.Type);<br>
> + if (!IsInFieldList) {<br>
> + // If this is a field list member, don't record its type index because it<br>
> + // doesn't have one. Only the outer field list has a type index.<br>
> + W->getOStream() << " (" << HexNumber(getNextTypeIndex()) << ")";<br>
> + }<br>
> + W->getOStream() << " {\n";<br>
> W->indent();<br>
> W->printEnum("TypeLeafKind", unsigned(Record.Type),<br>
> makeArrayRef(LeafTypeNames));<br>
> + if (Record.Type == LF_FIELDLIST) {<br>
> + // Record that we're in a field list so that members do not get assigned<br>
> + // type indices.<br>
> + assert(!IsInFieldList);<br>
> + IsInFieldList = true;<br>
> + }<br>
> return Error::success();<br>
> }<br>
><br>
> Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {<br>
> - if (Record.Type == LF_FIELDLIST)<br>
> - Name = "<field list>";<br>
> + if (Record.Type == LF_FIELDLIST) {<br>
> + assert(IsInFieldList);<br>
> + IsInFieldList = false;<br>
> + }<br>
><br>
> - // Always record some name for every type, even if Name is empty. CVUDTNames<br>
> - // is indexed by type index, and must have one entry for every type.<br>
> - recordType(Name);<br>
> + if (!IsInFieldList) {<br>
> + // Record every type that is not a field list member, even if Name is empty.<br>
> + // CVUDTNames is indexed by type index, and must have one entry for every<br>
> + // type. Field list members are not recorded, and are only referenced by<br>
> + // their containing field list record.<br>
> + recordType(Name);<br>
> + }<br>
><br>
> if (PrintRecordBytes)<br>
> W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));<br>
> @@ -232,6 +249,12 @@ Error CVTypeDumper::visitTypeEnd(const C<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> FieldListRecord &FieldList) {<br>
> + TypeDeserializer Deserializer(*this);<br>
> + CVTypeVisitor Visitor(Deserializer);<br>
> + if (auto EC = Visitor.visitFieldListMemberStream(FieldList.Data))<br>
> + return EC;<br>
> +<br>
> + Name = "<field list>";<br>
> return Error::success();<br>
> }<br>
><br>
> @@ -550,7 +573,6 @@ Error CVTypeDumper::visitUnknownMember(c<br>
> }<br>
><br>
> Error CVTypeDumper::visitUnknownType(const CVRecord<TypeLeafKind> &Record) {<br>
> - DictScope S(*W, "UnknownType");<br>
> W->printEnum("Kind", uint16_t(Record.Type), makeArrayRef(LeafTypeNames));<br>
> W->printNumber("Length", uint32_t(Record.Data.size()));<br>
> return Error::success();<br>
> @@ -558,7 +580,6 @@ Error CVTypeDumper::visitUnknownType(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> NestedTypeRecord &Nested) {<br>
> - DictScope S(*W, "NestedType");<br>
> printTypeIndex("Type", Nested.getNestedType());<br>
> W->printString("Name", Nested.getName());<br>
> Name = Nested.getName();<br>
> @@ -567,7 +588,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> OneMethodRecord &Method) {<br>
> - DictScope S(*W, "OneMethod");<br>
> MethodKind K = Method.getKind();<br>
> printMemberAttributes(Method.getAccess(), K, Method.getOptions());<br>
> printTypeIndex("Type", Method.getType());<br>
> @@ -581,7 +601,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> OverloadedMethodRecord &Method) {<br>
> - DictScope S(*W, "OverloadedMethod");<br>
> W->printHex("MethodCount", Method.getNumOverloads());<br>
> printTypeIndex("MethodListIndex", Method.getMethodList());<br>
> W->printString("Name", Method.getName());<br>
> @@ -591,7 +610,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> DataMemberRecord &Field) {<br>
> - DictScope S(*W, "DataMember");<br>
> printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,<br>
> MethodOptions::None);<br>
> printTypeIndex("Type", Field.getType());<br>
> @@ -603,7 +621,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> StaticDataMemberRecord &Field) {<br>
> - DictScope S(*W, "StaticDataMember");<br>
> printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,<br>
> MethodOptions::None);<br>
> printTypeIndex("Type", Field.getType());<br>
> @@ -614,14 +631,12 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> VFPtrRecord &VFTable) {<br>
> - DictScope S(*W, "VFPtr");<br>
> printTypeIndex("Type", VFTable.getType());<br>
> return Error::success();<br>
> }<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> EnumeratorRecord &Enum) {<br>
> - DictScope S(*W, "Enumerator");<br>
> printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,<br>
> MethodOptions::None);<br>
> W->printNumber("EnumValue", Enum.getValue());<br>
> @@ -632,7 +647,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> BaseClassRecord &Base) {<br>
> - DictScope S(*W, "BaseClass");<br>
> printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,<br>
> MethodOptions::None);<br>
> printTypeIndex("BaseType", Base.getBaseType());<br>
> @@ -642,7 +656,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> VirtualBaseClassRecord &Base) {<br>
> - DictScope S(*W, "VirtualBaseClass");<br>
> printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,<br>
> MethodOptions::None);<br>
> printTypeIndex("BaseType", Base.getBaseType());<br>
> @@ -654,7 +667,6 @@ Error CVTypeDumper::visitKnownRecord(con<br>
><br>
> Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,<br>
> ListContinuationRecord &Cont) {<br>
> - DictScope S(*W, "ListContinuation");<br>
> printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());<br>
> return Error::success();<br>
> }<br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp Tue Aug 16 18:28:54 2016<br>
> @@ -8,8 +8,9 @@<br>
> //===----------------------------------------------------------------------===//<br>
><br>
> #include "llvm/DebugInfo/CodeView/TypeRecord.h"<br>
> -#include "llvm/DebugInfo/CodeView/TypeIndex.h"<br>
> #include "llvm/DebugInfo/CodeView/RecordSerialization.h"<br>
> +#include "llvm/DebugInfo/CodeView/TypeIndex.h"<br>
> +#include "llvm/DebugInfo/MSF/ByteStream.h"<br>
><br>
> using namespace llvm;<br>
> using namespace llvm::codeview;<br>
> @@ -116,7 +117,9 @@ NestedTypeRecord::deserialize(TypeRecord<br>
><br>
> Expected<FieldListRecord><br>
> FieldListRecord::deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {<br>
> - return FieldListRecord(Data);<br>
> + auto FieldListData = Data;<br>
> + Data = ArrayRef<uint8_t>();<br>
> + return FieldListRecord(FieldListData);<br>
> }<br>
><br>
> Expected<ArrayRecord> ArrayRecord::deserialize(TypeRecordKind Kind,<br>
> @@ -448,7 +451,7 @@ bool PointerRecord::remapTypeIndices(Arr<br>
> bool Success = true;<br>
> Success &= remapIndex(IndexMap, ReferentType);<br>
> if (isPointerToMember())<br>
> - Success &= MemberInfo.remapTypeIndices(IndexMap);<br>
> + Success &= MemberInfo->remapTypeIndices(IndexMap);<br>
> return Success;<br>
> }<br>
><br>
><br>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)<br>
> +++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Tue Aug 16 18:28:54 2016<br>
> @@ -84,6 +84,11 @@ private:<br>
><br>
> Error visitKnownRecordImpl(FieldListRecord &Record) {<br>
> // Don't do anything, this will get written in the call to visitTypeEnd().<br>
> + TypeDeserializer Deserializer(*this);<br>
> + CVTypeVisitor Visitor(Deserializer);<br>
> +<br>
> + if (auto EC = Visitor.visitFieldListMemberStream(Record.Data))<br>
> + return std::move(EC);<br>
> return Error::success();<br>
> }<br>
><br>
> @@ -102,6 +107,7 @@ private:<br>
><br>
> TypeTableBuilder &DestStream;<br>
><br>
> + bool IsInFieldList{false};<br>
> size_t BeginIndexMapSize = 0;<br>
><br>
> /// Map from source type index to destination type index. Indexed by source<br>
> @@ -112,7 +118,10 @@ private:<br>
> } // end anonymous namespace<br>
><br>
> Error TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {<br>
> - if (Rec.Type != TypeLeafKind::LF_FIELDLIST)<br>
> + if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {<br>
> + assert(!IsInFieldList);<br>
> + IsInFieldList = true;<br>
> + } else<br>
> BeginIndexMapSize = IndexMap.size();<br>
> return Error::success();<br>
> }<br>
> @@ -121,7 +130,8 @@ Error TypeStreamMerger::visitTypeEnd(con<br>
> if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {<br>
> IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));<br>
> FieldBuilder.reset();<br>
> - } else {<br>
> + IsInFieldList = false;<br>
> + } else if (!IsInFieldList) {<br>
> assert(IndexMap.size() == BeginIndexMapSize + 1);<br>
> }<br>
> return Error::success();<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/COFF/big-type.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/big-type.ll?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/big-type.ll?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/COFF/big-type.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/COFF/big-type.ll Tue Aug 16 18:28:54 2016<br>
> @@ -5,6 +5,7 @@<br>
> ; CHECK-LABEL: FieldList (0x1000)<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: Enumerator {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: EnumValue: 5460<br>
> ; CHECK-NEXT: Name: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE5461<br>
> @@ -14,6 +15,7 @@<br>
> ; CHECK-LABEL: FieldList (0x1001)<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: Enumerator {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: EnumValue: 4095<br>
> ; CHECK-NEXT: Name: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE4096<br>
> @@ -23,6 +25,7 @@<br>
> ; CHECK-LABEL: FieldList (0x1002)<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: Enumerator {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: EnumValue: 2730<br>
> ; CHECK-NEXT: Name: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE2731<br>
> @@ -32,6 +35,7 @@<br>
> ; CHECK-LABEL: FieldList (0x1003)<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: Enumerator {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: EnumValue: 1365<br>
> ; CHECK-NEXT: Name: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE1366<br>
> @@ -41,6 +45,7 @@<br>
> ; CHECK-LABEL: FieldList (0x1004)<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: Enumerator {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: EnumValue: 0<br>
> ; CHECK-NEXT: Name: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE1<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/COFF/enum.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/enum.ll?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/enum.ll?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/COFF/enum.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/COFF/enum.ll Tue Aug 16 18:28:54 2016<br>
> @@ -8,6 +8,7 @@<br>
> ; CHECK: FieldList (0x1000) {<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: Enumerator {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: EnumValue: 0<br>
> ; CHECK-NEXT: Name: BLAH<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/COFF/inheritance.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inheritance.ll?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inheritance.ll?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/COFF/inheritance.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/COFF/inheritance.ll Tue Aug 16 18:28:54 2016<br>
> @@ -16,11 +16,13 @@<br>
> ; CHECK: FieldList ({{.*}}) {<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: BaseClass {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_BCLASS (0x1400)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: BaseType: B ({{.*}})<br>
> ; CHECK-NEXT: BaseOffset: 0x8<br>
> ; CHECK-NEXT: }<br>
> ; CHECK-NEXT: BaseClass {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_BCLASS (0x1400)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: BaseType: C ({{.*}})<br>
> ; CHECK-NEXT: BaseOffset: 0x18<br>
> @@ -31,6 +33,7 @@<br>
> ; CHECK: FieldList ({{.*}}) {<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: VirtualBaseClass {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_VBCLASS (0x1401)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: BaseType: A ({{.*}})<br>
> ; CHECK-NEXT: VBPtrType: const int* ({{.*}})<br>
> @@ -43,6 +46,7 @@<br>
> ; CHECK: FieldList ({{.*}}) {<br>
> ; CHECK-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; CHECK-NEXT: VirtualBaseClass {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_VBCLASS (0x1401)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: BaseType: A ({{.*}})<br>
> ; CHECK-NEXT: VBPtrType: const int* ({{.*}})<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/COFF/virtual-method-kinds.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/virtual-method-kinds.ll?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/virtual-method-kinds.ll?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/COFF/virtual-method-kinds.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/COFF/virtual-method-kinds.ll Tue Aug 16 18:28:54 2016<br>
> @@ -20,12 +20,14 @@<br>
> ; $ clang t.cpp -S -emit-llvm -g -gcodeview -o t.ll<br>
><br>
> ; CHECK: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: Virtual (0x1)<br>
> ; CHECK-NEXT: Type: void C::() ({{.*}})<br>
> ; CHECK-NEXT: Name: f<br>
> ; CHECK-NEXT: }<br>
> ; CHECK-NEXT: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: Virtual (0x1)<br>
> ; CHECK-NEXT: Type: void C::() ({{.*}})<br>
> @@ -33,12 +35,14 @@<br>
> ; CHECK-NEXT: }<br>
><br>
> ; CHECK: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: PureVirtual (0x5)<br>
> ; CHECK-NEXT: Type: void B::() ({{.*}})<br>
> ; CHECK-NEXT: Name: f<br>
> ; CHECK-NEXT: }<br>
> ; CHECK-NEXT: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: Virtual (0x1)<br>
> ; CHECK-NEXT: Type: void B::() ({{.*}})<br>
> @@ -46,6 +50,7 @@<br>
> ; CHECK-NEXT: }<br>
><br>
> ; CHECK: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: IntroducingVirtual (0x4)<br>
> ; CHECK-NEXT: Type: void A::() ({{.*}})<br>
> @@ -53,6 +58,7 @@<br>
> ; CHECK-NEXT: Name: f<br>
> ; CHECK-NEXT: }<br>
> ; CHECK-NEXT: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: PureIntroducingVirtual (0x6)<br>
> ; CHECK-NEXT: Type: void A::() ({{.*}})<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/COFF/virtual-methods.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/virtual-methods.ll?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/virtual-methods.ll?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/COFF/virtual-methods.ll (original)<br>
> +++ llvm/trunk/test/DebugInfo/COFF/virtual-methods.ll Tue Aug 16 18:28:54 2016<br>
> @@ -64,6 +64,7 @@<br>
><br>
> ; CHECK: FieldList ({{.*}}) {<br>
> ; CHECK: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: Virtual (0x1)<br>
> ; CHECK-NEXT: Type: int C::() ([[C_g]])<br>
> @@ -87,6 +88,7 @@<br>
><br>
> ; CHECK: FieldList ({{.*}}) {<br>
> ; CHECK: OneMethod {<br>
> +; CHECK-NEXT: TypeLeafKind: LF_ONEMETHOD (0x1511)<br>
> ; CHECK-NEXT: AccessSpecifier: Public (0x3)<br>
> ; CHECK-NEXT: MethodKind: Virtual (0x1)<br>
> ; CHECK-NEXT: Type: int D::() ([[D_g]])<br>
><br>
> Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=278869&r1=278868&r2=278869&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=278869&r1=278868&r2=278869&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)<br>
> +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Tue Aug 16 18:28:54 2016<br>
> @@ -111,26 +111,31 @@<br>
> ; EMPTY-NEXT: FieldList (0x1002) {<br>
> ; EMPTY-NEXT: TypeLeafKind: LF_FIELDLIST (0x1203)<br>
> ; EMPTY-NEXT: Enumerator {<br>
> +; EMPTY-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; EMPTY-NEXT: AccessSpecifier: Public (0x3)<br>
> ; EMPTY-NEXT: EnumValue: 1<br>
> ; EMPTY-NEXT: Name: apartment<br>
> ; EMPTY-NEXT: }<br>
> ; EMPTY-NEXT: Enumerator {<br>
> +; EMPTY-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; EMPTY-NEXT: AccessSpecifier: Public (0x3)<br>
> ; EMPTY-NEXT: EnumValue: 2<br>
> ; EMPTY-NEXT: Name: single<br>
> ; EMPTY-NEXT: }<br>
> ; EMPTY-NEXT: Enumerator {<br>
> +; EMPTY-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; EMPTY-NEXT: AccessSpecifier: Public (0x3)<br>
> ; EMPTY-NEXT: EnumValue: 3<br>
> ; EMPTY-NEXT: Name: free<br>
> ; EMPTY-NEXT: }<br>
> ; EMPTY-NEXT: Enumerator {<br>
> +; EMPTY-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; EMPTY-NEXT: AccessSpecifier: Public (0x3)<br>
> ; EMPTY-NEXT: EnumValue: 4<br>
> ; EMPTY-NEXT: Name: neutral<br>
> ; EMPTY-NEXT: }<br>
> ; EMPTY-NEXT: Enumerator {<br>
> +; EMPTY-NEXT: TypeLeafKind: LF_ENUMERATE (0x1502)<br>
> ; EMPTY-NEXT: AccessSpecifier: Public (0x3)<br>
> ; EMPTY-NEXT: EnumValue: 5<br>
> ; EMPTY-NEXT: Name: both<br>
><br>
> Added: llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test?rev=278869&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test?rev=278869&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test (added)<br>
> +++ llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test Tue Aug 16 18:28:54 2016<br>
> @@ -0,0 +1,1087 @@<br>
> +; RUN: llvm-pdbdump pdb2yaml -tpi-stream %p/Inputs/empty.pdb \<br>
> +; RUN: | FileCheck -check-prefix=YAML %s<br>
> +<br>
> +YAML: ---<br>
> +YAML: MSF:<br>
> +YAML: SuperBlock:<br>
> +YAML: BlockSize: 4096<br>
> +YAML: FreeBlockMap: 2<br>
> +YAML: NumBlocks: 25<br>
> +YAML: NumDirectoryBytes: 136<br>
> +YAML: Unknown1: 0<br>
> +YAML: BlockMapAddr: 24<br>
> +YAML: NumDirectoryBlocks: 1<br>
> +YAML: DirectoryBlocks: [ 23 ]<br>
> +YAML: NumStreams: 0<br>
> +YAML: FileSize: 102400<br>
> +YAML: TpiStream:<br>
> +YAML: Version: VC80<br>
> +YAML: Records:<br>
> +YAML: - Kind: LF_ARGLIST<br>
> +YAML: ArgList:<br>
> +YAML: ArgIndices: [ ]<br>
> +YAML: - Kind: LF_PROCEDURE<br>
> +YAML: Procedure:<br>
> +YAML: ReturnType: 116<br>
> +YAML: CallConv: NearC<br>
> +YAML: Options: [ None ]<br>
> +YAML: ParameterCount: 0<br>
> +YAML: ArgumentList: 4096<br>
> +YAML: - Kind: LF_FIELDLIST<br>
> +YAML: FieldList:<br>
> +YAML: Kind: LF_ENUMERATE<br>
> +YAML: Enumerator:<br>
> +YAML: Access: Public<br>
> +YAML: Value: 1<br>
> +YAML: Name: apartment<br>
> +YAML: Kind: LF_ENUMERATE<br>
> +YAML: Enumerator:<br>
> +YAML: Access: Public<br>
> +YAML: Value: 2<br>
> +YAML: Name: single<br>
> +YAML: Kind: LF_ENUMERATE<br>
> +YAML: Enumerator:<br>
> +YAML: Access: Public<br>
> +YAML: Value: 3<br>
> +YAML: Name: free<br>
> +YAML: Kind: LF_ENUMERATE<br>
> +YAML: Enumerator:<br>
> +YAML: Access: Public<br>
> +YAML: Value: 4<br>
> +YAML: Name: neutral<br>
> +YAML: Kind: LF_ENUMERATE<br>
> +YAML: Enumerator:<br>
> +YAML: Access: Public<br>
> +YAML: Value: 5<br>
> +YAML: Name: both<br>
> +YAML: - Kind: LF_ENUM<br>
> +YAML: Enum:<br>
> +YAML: NumEnumerators: 5<br>
> +YAML: Options: [ None, Nested, HasUniqueName ]<br>
> +YAML: FieldList: 4098<br>
> +YAML: Name: '__vc_attributes::threadingAttribute::threading_e'<br>
> +YAML: UniqueName: '.?AW4threading_e@threadingAttribute@__vc_attributes@@'<br>
> +YAML: UnderlyingType: 116<br>
> +YAML: - Kind: LF_STRUCTURE<br>
> +YAML: Class:<br>
> +YAML: MemberCount: 0<br>
> +YAML: Options: [ None, ForwardReference, HasUniqueName ]<br>
> +YAML: FieldList: 0<br>
> +YAML: Name: '__vc_attributes::threadingAttribute'<br>
> +YAML: UniqueName: '.?AUthreadingAttribute@__vc_attributes@@'<br>
> +YAML: Hfa: None<br>
> +YAML: WinRTKind: None<br>
> +YAML: DerivationList: 0<br>
> +YAML: VTableShape: 0<br>
> +YAML: Size: 0<br>
> +YAML: - Kind: LF_POINTER<br>
> +YAML: Pointer:<br>
> +YAML: ReferentType: 410</blockquote></div>