[llvm] r285836 - Add CodeViewRecordIO for reading and writing.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 2 10:05:20 PDT 2016


Author: zturner
Date: Wed Nov  2 12:05:19 2016
New Revision: 285836

URL: http://llvm.org/viewvc/llvm-project?rev=285836&view=rev
Log:
Add CodeViewRecordIO for reading and writing.

Using a pattern similar to that of YamlIO, this allows
us to have a single codepath for translating codeview
records to and from serialized byte streams.  The
current patch only hooks this up to the reading of
CodeView type records.  A subsequent patch will hook
it up for writing of CodeView type records, and then a
third patch will hook up the reading and writing of
CodeView symbols.

Differential Revision: https://reviews.llvm.org/D26040

Added:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
    llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
    llvm/trunk/include/llvm/DebugInfo/MSF/StreamWriter.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
    llvm/trunk/lib/DebugInfo/MSF/StreamWriter.cpp
    llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test
    llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h?rev=285836&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h Wed Nov  2 12:05:19 2016
@@ -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 <stdint.h>
+#include <type_traits>
+
+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 <typename T> Error mapInteger(T &Value) {
+    if (isWriting())
+      return Writer->writeInteger(Value);
+
+    return Reader->readInteger(Value);
+  }
+
+  template <typename T> Error mapEnum(T &Value) {
+    using U = typename std::underlying_type<T>::type;
+    U X;
+    if (isWriting())
+      X = static_cast<U>(Value);
+
+    if (auto EC = mapInteger(X))
+      return EC;
+    if (isReading())
+      Value = static_cast<T>(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 <typename SizeType, typename T, typename ElementMapper>
+  Error mapVectorN(T &Items, const ElementMapper &Mapper) {
+    SizeType Size;
+    if (isWriting()) {
+      Size = static_cast<SizeType>(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 <typename T, typename ElementMapper>
+  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<uint8_t> &Bytes);
+
+  Error skipPadding();
+
+private:
+  Error writeEncodedSignedInteger(const int64_t &Value);
+  Error writeEncodedUnsignedInteger(const uint64_t &Value);
+
+  Optional<ActiveRecord> CurrentRecord;
+
+  msf::StreamReader *Reader = nullptr;
+  msf::StreamWriter *Writer = nullptr;
+};
+}
+}
+
+#endif

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h Wed Nov  2 12:05:19 2016
@@ -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<uint8_t> 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<MappingInfo>(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);                               \
-  }
-#define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
-    return defaultVisitKnownMember(CVR, Record);                               \
+    return visitKnownRecordImpl<Name##Record>(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"
 
-protected:
-  template <typename T>
-  Error deserializeRecord(msf::StreamReader &Reader, TypeLeafKind Kind,
-                          T &Record) const {
-    TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);
-    auto ExpectedRecord = T::deserialize(RK, Reader);
-    if (!ExpectedRecord)
-      return ExpectedRecord.takeError();
-    Record = std::move(*ExpectedRecord);
-    return Error::success();
+private:
+  template <typename RecordType>
+  Error visitKnownRecordImpl(CVType &CVR, RecordType &Record) {
+    return Mapping->Mapping.visitKnownRecord(CVR, Record);
   }
 
-private:
-  template <typename T> Error defaultVisitKnownRecord(CVType &CVR, T &Record) {
-    msf::ByteStream S(CVR.content());
-    msf::StreamReader SR(S);
-    if (auto EC = deserializeRecord(SR, CVR.Type, Record))
+  std::unique_ptr<MappingInfo> 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();
   }
-  template <typename T>
-  Error defaultVisitKnownMember(CVMemberRecord &CVMR, T &Record) {
-    msf::ByteStream S(CVMR.Data);
-    msf::StreamReader SR(S);
-    if (auto EC = deserializeRecord(SR, CVMR.Kind, Record))
+
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
+  Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
+    return visitKnownMemberImpl<Name##Record>(CVR, Record);                    \
+  }
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "TypeRecords.def"
+
+private:
+  template <typename RecordType>
+  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;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h Wed Nov  2 12:05:19 2016
@@ -101,6 +101,7 @@ public:
       : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(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(); }

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h Wed Nov  2 12:05:19 2016
@@ -43,10 +43,20 @@ typedef msf::VarStreamArray<CVType> CVTy
 
 /// 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<uint16_t>(Access)) {}
+
+  MemberAttributes(MemberAccess Access, MethodKind Kind, MethodOptions Flags) {
+    Attrs = static_cast<uint16_t>(Access);
+    Attrs |= (static_cast<uint16_t>(Kind) << MethodKindShift);
+    Attrs |= static_cast<uint16_t>(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<TypeIndex> IndexMap);
 
-  static Expected<MemberPointerInfo> 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<TypeIndex> IndexMap);
 
-  static Expected<ModifierRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<ProcedureRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<MemberFunctionRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<MemberFuncIdRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<ArgListRecord> deserialize(TypeRecordKind Kind,
-                                             msf::StreamReader &Reader);
-
   ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
 
-  static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
-
   std::vector<TypeIndex> 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),
+        Attrs(Attrs) {}
+
+  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) {}
+        Attrs(calcAttrs(PK, PM, PO, Size)), MemberInfo(Member) {}
 
-  PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
-                PointerOptions Options, uint8_t Size,
+  PointerRecord(TypeIndex ReferentType, uint32_t Attrs,
                 const MemberPointerInfo &Member)
       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
-        PtrKind(Kind), Mode(Mode), Options(Options), Size(Size),
-        MemberInfo(Member) {}
+        Attrs(Attrs), MemberInfo(Member) {}
 
   /// Rewrite member type indices with IndexMap. Returns false if a type index
   /// is not in the map.
   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
 
-  static Expected<PointerRecord> 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<PointerKind>((Attrs >> PointerKindShift) &
+                                    PointerKindMask);
+  }
+  PointerMode getMode() const {
+    return static_cast<PointerMode>((Attrs >> PointerModeShift) &
+                                    PointerModeMask);
+  }
+  PointerOptions getOptions() const {
+    return static_cast<PointerOptions>(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<MemberPointerInfo> 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<uint32_t>(PK);
+    A |= static_cast<uint32_t>(PO);
+    A |= (static_cast<uint32_t>(PM) << PointerModeShift);
+    A |= (static_cast<uint32_t>(Size) << PointerSizeShift);
+    return A;
+  }
 };
 
 // LF_NESTTYPE
@@ -414,21 +349,11 @@ public:
   /// is not in the map.
   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
 
-  static Expected<NestedTypeRecord> 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<TypeIndex> IndexMap) { return false; }
 
-  static Expected<FieldListRecord> deserialize(TypeRecordKind Kind,
-                                               msf::StreamReader &Reader);
-
   ArrayRef<uint8_t> Data;
 };
 
@@ -461,9 +383,6 @@ public:
   /// is not in the map.
   bool remapTypeIndices(ArrayRef<TypeIndex> IndexMap);
 
-  static Expected<ArrayRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<ClassRecord> deserialize(TypeRecordKind Kind,
-                                           msf::StreamReader &Reader);
-
-  HfaKind getHfa() const { return Hfa; }
-  WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
+  HfaKind getHfa() const {
+    uint16_t Value = static_cast<uint16_t>(Options);
+    Value = (Value & HfaKindMask) >> HfaKindShift;
+    return static_cast<HfaKind>(Value);
+  }
+  WindowsRTClassKind getWinRTKind() const {
+    uint16_t Value = static_cast<uint16_t>(Options);
+    Value = (Value & WinRTKindMask) >> WinRTKindShift;
+    return static_cast<WindowsRTClassKind>(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<UnionRecord> deserialize(TypeRecordKind Kind,
-                                           msf::StreamReader &Reader);
-
-  HfaKind getHfa() const { return Hfa; }
+  HfaKind getHfa() const {
+    uint16_t Value = static_cast<uint16_t>(Options);
+    Value = (Value & HfaKindMask) >> HfaKindShift;
+    return static_cast<HfaKind>(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<TypeIndex> IndexMap);
 
-  static Expected<EnumRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<BitFieldRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<VFTableShapeRecord> deserialize(TypeRecordKind Kind,
-                                                  msf::StreamReader &Reader);
-
   ArrayRef<VFTableSlotKind> getSlots() const {
     if (!SlotsRef.empty())
       return SlotsRef;
@@ -685,16 +540,6 @@ public:
   uint32_t getEntryCount() const { return getSlots().size(); }
   ArrayRef<VFTableSlotKind> SlotsRef;
   std::vector<VFTableSlotKind> 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<TypeIndex> IndexMap);
 
-  static Expected<TypeServer2Record> 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<TypeIndex> IndexMap);
 
-  static Expected<StringIdRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<FuncIdRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<UdtSourceLineRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<UdtModSourceLineRecord>
-  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<TypeIndex> IndexMap);
 
-  static Expected<BuildInfoRecord> deserialize(TypeRecordKind Kind,
-                                               msf::StreamReader &Reader);
-
   ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
   SmallVector<TypeIndex, 4> 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<StringRef> 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<StringRef> &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<TypeIndex> IndexMap);
 
-  static Expected<VFTableRecord> 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<StringRef> getMethodNames() const {
-    if (!MethodNamesRef.empty())
-      return MethodNamesRef;
-    return MethodNames;
+    return makeArrayRef(MethodNames).drop_front();
   }
+
   TypeIndex CompleteClass;
   TypeIndex OverriddenVFTable;
-  ulittle32_t VFPtrOffset;
-  StringRef Name;
-  ArrayRef<StringRef> MethodNamesRef;
+  uint32_t VFPtrOffset;
   std::vector<StringRef> 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 TypeRecor
 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<TypeIndex> IndexMap);
 
-  static Expected<OneMethodRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<MethodOverloadListRecord>
-  deserialize(TypeRecordKind Kind, msf::StreamReader &Reader);
-
   ArrayRef<OneMethodRecord> getMethods() const { return Methods; }
   std::vector<OneMethodRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<OverloadedMethodRecord>
-  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<TypeIndex> IndexMap);
 
-  static Expected<DataMemberRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<StaticDataMemberRecord>
-  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<TypeIndex> IndexMap);
 
-  static Expected<EnumeratorRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<VFPtrRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<BaseClassRecord> 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<TypeIndex> IndexMap);
 
-  static Expected<VirtualBaseClassRecord>
-  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<TypeIndex> IndexMap);
 
-  static Expected<ListContinuationRecord>
-  deserialize(TypeRecordKind Kind, msf::StreamReader &Reader);
   TypeIndex ContinuationIndex;
-
-private:
-  struct Layout {
-    ulittle16_t Pad0;
-    TypeIndex ContinuationIndex;
-  };
 };
 
 }

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h?rev=285836&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h Wed Nov  2 12:05:19 2016
@@ -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<TypeLeafKind> TypeKind;
+
+  CodeViewRecordIO IO;
+};
+}
+}
+
+#endif

Modified: llvm/trunk/include/llvm/DebugInfo/MSF/StreamWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/MSF/StreamWriter.h?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/MSF/StreamWriter.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/MSF/StreamWriter.h Wed Nov  2 12:05:19 2016
@@ -25,11 +25,18 @@ namespace msf {
 
 class StreamWriter {
 public:
+  StreamWriter() {}
   StreamWriter(WritableStreamRef Stream);
 
   Error writeBytes(ArrayRef<uint8_t> 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

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Wed Nov  2 12:05:19 2016
@@ -1690,9 +1690,9 @@ TypeIndex CodeViewDebug::lowerTypeClass(
   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::lowerCompleteTy
 
   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(
   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::lowerCompleteTy
   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(cons
       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");

Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Wed Nov  2 12:05:19 2016
@@ -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
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp Wed Nov  2 12:05:19 2016
@@ -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 <typename T>
 static Expected<CVMemberRecord>
-deserializeMemberRecord(msf::StreamReader &Reader, TypeLeafKind Kind) {
-  msf::StreamReader OldReader = Reader;
-  TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);
-  auto ExpectedRecord = T::deserialize(RK, Reader);
-  if (!ExpectedRecord)
-    return ExpectedRecord.takeError();
-  assert(Reader.bytesRemaining() < OldReader.bytesRemaining());
-  if (auto EC = skipPadding(Reader))
-    return std::move(EC);
+deserializeMemberRecord(FieldListDeserializer &Deserializer,
+                        msf::StreamReader &Reader, TypeLeafKind Kind) {
+  T MR(static_cast<TypeRecordKind>(Kind));
+  CVMemberRecord CVR;
+  CVR.Kind = Kind;
 
-  CVMemberRecord CVMR;
-  CVMR.Kind = Kind;
-
-  uint32_t RecordLength = OldReader.bytesRemaining() - Reader.bytesRemaining();
-  if (auto EC = OldReader.readBytes(CVMR.Data, RecordLength))
+  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);
 
-  return CVMR;
+  return CVR;
 }
 
 CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
@@ -138,22 +123,28 @@ Error CVTypeVisitor::visitTypeStream(con
 }
 
 template <typename MR>
-static Error visitKnownMember(msf::StreamReader &Reader, TypeLeafKind Leaf,
+static Error visitKnownMember(FieldListDeserializer &Deserializer,
+                              msf::StreamReader &Reader, TypeLeafKind Leaf,
                               TypeVisitorCallbacks &Callbacks) {
-  auto ExpectedRecord = deserializeMemberRecord<MR>(Reader, Leaf);
-  if (!ExpectedRecord)
-    return ExpectedRecord.takeError();
-  CVMemberRecord &Record = *ExpectedRecord;
-  if (auto EC = Callbacks.visitMemberBegin(Record))
+  MR Record(static_cast<TypeRecordKind>(Leaf));
+  CVMemberRecord CVR;
+  CVR.Kind = Leaf;
+
+  if (auto EC = Callbacks.visitMemberBegin(CVR))
     return EC;
-  if (auto EC = visitKnownMember<MR>(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::visitFieldListMembe
           cv_error_code::unknown_member_record);
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
   case EnumName: {                                                             \
-    if (auto EC = visitKnownMember<Name##Record>(Reader, Leaf, Callbacks))     \
+    if (auto EC = visitKnownMember<Name##Record>(Deserializer, Reader, Leaf,   \
+                                                 Pipeline))                    \
       return EC;                                                               \
     break;                                                                     \
   }

Added: llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp?rev=285836&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp Wed Nov  2 12:05:19 2016
@@ -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<uint8_t> &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<uint64_t>(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<int8_t>::min()) {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_CHAR)))
+      return EC;
+    if (auto EC = Writer->writeInteger(static_cast<int8_t>(Value)))
+      return EC;
+  } else if (Value >= std::numeric_limits<int16_t>::min()) {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_SHORT)))
+      return EC;
+    if (auto EC = Writer->writeInteger(static_cast<int16_t>(Value)))
+      return EC;
+  } else if (Value >= std::numeric_limits<int32_t>::min()) {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_LONG)))
+      return EC;
+    if (auto EC = Writer->writeInteger(static_cast<int32_t>(Value)))
+      return EC;
+  } else {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(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<uint16_t>(Value)))
+      return EC;
+  } else if (Value <= std::numeric_limits<uint16_t>::max()) {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_USHORT)))
+      return EC;
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(Value)))
+      return EC;
+  } else if (Value <= std::numeric_limits<uint32_t>::max()) {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_ULONG)))
+      return EC;
+    if (auto EC = Writer->writeInteger(static_cast<uint32_t>(Value)))
+      return EC;
+  } else {
+    if (auto EC = Writer->writeInteger(static_cast<uint16_t>(LF_UQUADWORD)))
+      return EC;
+    if (auto EC = Writer->writeInteger(Value))
+      return EC;
+  }
+
+  return Error::success();
+}

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Wed Nov  2 12:05:19 2016
@@ -268,12 +268,7 @@ Error CVTypeDumper::visitMemberEnd(CVMem
 
 Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &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;
 

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeRecord.cpp Wed Nov  2 12:05:19 2016
@@ -17,384 +17,6 @@ using namespace llvm;
 using namespace llvm::codeview;
 
 //===----------------------------------------------------------------------===//
-// Type record deserialization
-//===----------------------------------------------------------------------===//
-
-Expected<MemberPointerInfo>
-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<PointerToMemberRepresentation>(R);
-  return MemberPointerInfo(T, PMR);
-}
-
-Expected<ModifierRecord>
-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<ModifierOptions>(O);
-  return ModifierRecord(M, MO);
-}
-
-Expected<ProcedureRecord>
-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>
-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>
-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> ArgListRecord::deserialize(TypeRecordKind Kind,
-                                                   msf::StreamReader &Reader) {
-  if (Kind != TypeRecordKind::StringList && Kind != TypeRecordKind::ArgList)
-    return make_error<CodeViewError>(
-        cv_error_code::corrupt_record,
-        "ArgListRecord contains unexpected TypeRecordKind");
-
-  const Layout *L = nullptr;
-  ArrayRef<TypeIndex> Indices;
-  CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
-  return ArgListRecord(Kind, Indices);
-}
-
-Expected<PointerRecord> 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<PointerOptions>(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>
-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>
-FieldListRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
-  ArrayRef<uint8_t> Data;
-  if (auto EC = Reader.readBytes(Data, Reader.bytesRemaining()))
-    return std::move(EC);
-  return FieldListRecord(Data);
-}
-
-Expected<ArrayRecord> 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> 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<WindowsRTClassKind>(WrtValue);
-  uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift;
-  HfaKind Hfa = static_cast<HfaKind>(HfaMask);
-
-  ClassOptions Options = static_cast<ClassOptions>(Props);
-  return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList,
-                     L->DerivedFrom, L->VShape, Size, Name, UniqueName);
-}
-
-Expected<UnionRecord> 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<HfaKind>(HfaMask);
-  ClassOptions Options = static_cast<ClassOptions>(Props);
-  return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name,
-                     UniqueName);
-}
-
-Expected<EnumRecord> 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<ClassOptions>(P);
-  return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name,
-                    UniqueName, L->UnderlyingType);
-}
-
-Expected<BitFieldRecord>
-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>
-VFTableShapeRecord::deserialize(TypeRecordKind Kind,
-                                msf::StreamReader &Reader) {
-  const Layout *L = nullptr;
-  if (auto EC = Reader.readObject(L))
-    return std::move(EC);
-
-  std::vector<VFTableSlotKind> 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<VFTableSlotKind>(Value));
-    if (--Count > 0) {
-      Value = (Data & 0xF0) >> 4;
-      Slots.push_back(static_cast<VFTableSlotKind>(Value));
-      --Count;
-    }
-  }
-
-  return VFTableShapeRecord(Slots);
-}
-
-Expected<TypeServer2Record>
-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>
-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> 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>
-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>
-BuildInfoRecord::deserialize(TypeRecordKind Kind, msf::StreamReader &Reader) {
-  const Layout *L = nullptr;
-  ArrayRef<TypeIndex> Indices;
-  CV_DESERIALIZE(Reader, L, CV_ARRAY_FIELD_N(Indices, L->NumArgs));
-  return BuildInfoRecord(Indices);
-}
-
-Expected<VFTableRecord> VFTableRecord::deserialize(TypeRecordKind Kind,
-                                                   msf::StreamReader &Reader) {
-  const Layout *L = nullptr;
-  StringRef Name;
-  std::vector<StringRef> Names;
-  CV_DESERIALIZE(Reader, L, Name, CV_ARRAY_FIELD_TAIL(Names));
-  return VFTableRecord(L->CompleteClass, L->OverriddenVFTable, L->VFPtrOffset,
-                       Name, Names);
-}
-
-Expected<OneMethodRecord>
-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<CodeViewError>(cv_error_code::corrupt_record,
-                                     "Invalid VFTableOffset");
-  return Method;
-}
-
-Expected<MethodOverloadListRecord>
-MethodOverloadListRecord::deserialize(TypeRecordKind Kind,
-                                      msf::StreamReader &Reader) {
-  std::vector<OneMethodRecord> 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<CodeViewError>(cv_error_code::corrupt_record,
-                                       "Invalid VFTableOffset");
-  }
-  return MethodOverloadListRecord(Methods);
-}
-
-Expected<OverloadedMethodRecord>
-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>
-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>
-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>
-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> 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>
-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>
-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>
-ListContinuationRecord::deserialize(TypeRecordKind Kind,
-                                    msf::StreamReader &Reader) {
-  const Layout *L = nullptr;
-  CV_DESERIALIZE(Reader, L);
-  return ListContinuationRecord(L->ContinuationIndex);
-}
-
-//===----------------------------------------------------------------------===//
 // Type index remapping
 //===----------------------------------------------------------------------===//
 

Added: llvm/trunk/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeRecordMapping.cpp?rev=285836&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeRecordMapping.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeRecordMapping.cpp Wed Nov  2 12:05:19 2016
@@ -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 <typename T> Error operator()(CodeViewRecordIO &IO, T &N) const {
+    return IO.mapInteger(N);
+  }
+};
+
+struct MapEnum {
+  template <typename T> 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<uint32_t>(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<VFTableSlotKind> 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<uint8_t>(Slots[SlotIndex]) << 4;
+      if ((SlotIndex + 1) < Slots.size()) {
+        Byte |= static_cast<uint8_t>(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<VFTableSlotKind>(Byte & 0xF));
+      if ((I + 1) < Size)
+        Record.Slots.push_back(static_cast<VFTableSlotKind>(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<uint16_t>(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();
+}

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Wed Nov  2 12:05:19 2016
@@ -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;

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp Wed Nov  2 12:05:19 2016
@@ -72,13 +72,7 @@ TypeIndex TypeTableBuilder::writeKnownTy
   TypeRecordBuilder Builder(Record.getKind());
 
   Builder.writeTypeIndex(Record.getReferentType());
-  uint32_t flags = static_cast<uint32_t>(Record.getOptions()) |
-                   (Record.getSize() << PointerRecord::PointerSizeShift) |
-                   (static_cast<uint32_t>(Record.getMode())
-                    << PointerRecord::PointerModeShift) |
-                   (static_cast<uint32_t>(Record.getPointerKind())
-                    << PointerRecord::PointerKindShift);
-  Builder.writeUInt32(flags);
+  Builder.writeUInt32(Record.Attrs);
 
   if (Record.isPointerToMember()) {
     const MemberPointerInfo &M = Record.getMemberInfo();

Modified: llvm/trunk/lib/DebugInfo/MSF/StreamWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/MSF/StreamWriter.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/MSF/StreamWriter.cpp (original)
+++ llvm/trunk/lib/DebugInfo/MSF/StreamWriter.cpp Wed Nov  2 12:05:19 2016
@@ -25,6 +25,8 @@ Error StreamWriter::writeBytes(ArrayRef<
   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_
   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;

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-types.test Wed Nov  2 12:05:19 2016
@@ -31,27 +31,27 @@ YAML:     - Kind:            LF_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::threadingAttribute'
 YAML:         UniqueName:      '.?AUthreadingAttribute at __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_METHODLI
 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, H
 YAML:         FieldList:       4106
 YAML:         Name:            '__vc_attributes::threadingAttribute'
 YAML:         UniqueName:      '.?AUthreadingAttribute at __vc_attributes@@'
-YAML:         Hfa:             None
-YAML:         WinRTKind:       None
 YAML:         DerivationList:  0
 YAML:         VTableShape:     0
 YAML:         Size:            4
@@ -152,17 +141,17 @@ YAML:     - Kind:            LF_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::event_receiverAttribute'
 YAML:         UniqueName:      '.?AUevent_receiverAttribute at __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_METHODLI
 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, H
 YAML:         FieldList:       4118
 YAML:         Name:            '__vc_attributes::event_receiverAttribute'
 YAML:         UniqueName:      '.?AUevent_receiverAttribute at __vc_attributes@@'
-YAML:         Hfa:             None
-YAML:         WinRTKind:       None
 YAML:         DerivationList:  0
 YAML:         VTableShape:     0
 YAML:         Size:            8
@@ -288,17 +264,17 @@ YAML:     - Kind:            LF_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::aggregatableAttribute'
 YAML:         UniqueName:      '.?AUaggregatableAttribute at __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_METHODLI
 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, H
 YAML:         FieldList:       4128
 YAML:         Name:            '__vc_attributes::aggregatableAttribute'
 YAML:         UniqueName:      '.?AUaggregatableAttribute at __vc_attributes@@'
-YAML:         Hfa:             None
-YAML:         WinRTKind:       None
 YAML:         DerivationList:  0
 YAML:         VTableShape:     0
 YAML:         Size:            4
@@ -407,12 +372,12 @@ YAML:     - Kind:            LF_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::event_sourceAttribute'
 YAML:         UniqueName:      '.?AUevent_sourceAttribute at __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_METHODLI
 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, H
 YAML:         FieldList:       4139
 YAML:         Name:            '__vc_attributes::event_sourceAttribute'
 YAML:         UniqueName:      '.?AUevent_sourceAttribute at __vc_attributes@@'
-YAML:         Hfa:             None
-YAML:         WinRTKind:       None
 YAML:         DerivationList:  0
 YAML:         VTableShape:     0
 YAML:         Size:            12
@@ -529,32 +483,32 @@ YAML:     - Kind:            LF_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::moduleAttribute'
 YAML:         UniqueName:      '.?AUmoduleAttribute at __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, C
 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_METHODLI
 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, H
 YAML:         FieldList:       4153
 YAML:         Name:            '__vc_attributes::moduleAttribute'
 YAML:         UniqueName:      '.?AUmoduleAttribute at __vc_attributes@@'
-YAML:         Hfa:             None
-YAML:         WinRTKind:       None
 YAML:         DerivationList:  0
 YAML:         VTableShape:     0
 YAML:         Size:            56
@@ -770,152 +708,152 @@ YAML:     - Kind:            LF_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::helper_attributes::usageAttribute'
 YAML:         UniqueName:      '.?AUusageAttribute at 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
 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, H
 YAML:         FieldList:       4161
 YAML:         Name:            '__vc_attributes::helper_attributes::usageAttribute'
 YAML:         UniqueName:      '.?AUusageAttribute at 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_FIELDLIS
 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, F
 YAML:         FieldList:       0
 YAML:         Name:            '__vc_attributes::helper_attributes::v1_alttypeAttribute'
 YAML:         UniqueName:      '.?AUv1_alttypeAttribute at 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_
 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, H
 YAML:         FieldList:       4169
 YAML:         Name:            '__vc_attributes::helper_attributes::v1_alttypeAttribute'
 YAML:         UniqueName:      '.?AUv1_alttypeAttribute at helper_attributes@__vc_attributes@@'
-YAML:         Hfa:             None
-YAML:         WinRTKind:       None
 YAML:         DerivationList:  0
 YAML:         VTableShape:     0
 YAML:         Size:            4

Modified: llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp?rev=285836&r1=285835&r2=285836&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp Wed Nov  2 12:05:19 2016
@@ -300,8 +300,6 @@ void MappingTraits<ClassRecord>::mapping
   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<UnionRecord>::mapping
   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<VFTableRecord>::mappi
   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<TypeServer2Record>::m
 
 void MappingTraits<PointerRecord>::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<NestedTypeRecord>::ma
 
 void MappingTraits<OneMethodRecord>::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<OverloadedMethodRecor
 }
 
 void MappingTraits<DataMemberRecord>::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<DataMemberRecord>::ma
 
 void MappingTraits<StaticDataMemberRecord>::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<VFPtrRecord>::mapping
 }
 
 void MappingTraits<EnumeratorRecord>::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<BaseClassRecord>::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<VirtualBaseClassRecord>::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<pdb::yaml::P
   static void mapping(IO &IO, pdb::yaml::PdbTpiFieldListRecord &Obj,
                       pdb::yaml::SerializationContext &Context) {
     codeview::TypeVisitorCallbackPipeline Pipeline;
-    codeview::TypeDeserializer Deserializer;
+
+    msf::ByteStream Data(Obj.Record.Data);
+    msf::StreamReader FieldReader(Data);
+    codeview::FieldListDeserializer Deserializer(FieldReader);
     codeview::TypeSerializationVisitor Serializer(Context.FieldListBuilder,
                                                   Context.TypeTableBuilder);
     pdb::TpiHashUpdater Hasher;




More information about the llvm-commits mailing list