[llvm] r269216 - Refactor CodeView type records to use common code.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 10:47:35 PDT 2016


Author: zturner
Date: Wed May 11 12:47:35 2016
New Revision: 269216

URL: http://llvm.org/viewvc/llvm-project?rev=269216&view=rev
Log:
Refactor CodeView type records to use common code.

Differential Revision: http://reviews.llvm.org/D20138
Reviewed By: rnk

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecords.def
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeStream.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Wed May 11 12:47:35 2016
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/CodeView/RecordIterator.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/ErrorOr.h"
 
 namespace llvm {
 namespace codeview {
@@ -42,12 +43,10 @@ public:
   /// FIXME: Make the visitor interpret the trailing bytes so that clients don't
   /// need to.
 #define TYPE_RECORD(ClassName, LeafEnum)                                       \
-  void visit##ClassName(TypeLeafKind LeafType, const ClassName *Record,        \
-                        ArrayRef<uint8_t> LeafData) {}
+  void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {}
 #define TYPE_RECORD_ALIAS(ClassName, LeafEnum)
 #define MEMBER_RECORD(ClassName, LeafEnum)                                     \
-  void visit##ClassName(TypeLeafKind LeafType, const ClassName *Record,        \
-                        ArrayRef<uint8_t> &FieldData) {}
+  void visit##ClassName(TypeLeafKind LeafType, ClassName &Record) {}
 #define MEMBER_RECORD_ALIAS(ClassName, LeafEnum)
 #include "TypeRecords.def"
 
@@ -68,10 +67,11 @@ public:
       break;
 #define TYPE_RECORD(ClassName, LeafEnum)                                       \
   case LeafEnum: {                                                             \
-    const ClassName *Rec;                                                      \
-    if (!CVTypeVisitor::consumeObject(LeafData, Rec))                          \
-      return;                                                                  \
-    DerivedThis->visit##ClassName(Record.Type, Rec, LeafData);                 \
+    TypeRecordKind RK = static_cast<TypeRecordKind>(LeafEnum);                 \
+    auto Result = ClassName::deserialize(RK, LeafData);                        \
+    if (Result.getError())                                                     \
+      return parseError();                                                     \
+    DerivedThis->visit##ClassName(Record.Type, *Result);                       \
     break;                                                                     \
   }
 #include "TypeRecords.def"
@@ -120,10 +120,11 @@ public:
         return parseError();
 #define MEMBER_RECORD(ClassName, LeafEnum)                                     \
   case LeafEnum: {                                                             \
-    const ClassName *Rec;                                                      \
-    if (!CVTypeVisitor::consumeObject(FieldData, Rec))                         \
-      return;                                                                  \
-    static_cast<Derived *>(this)->visit##ClassName(Leaf, Rec, FieldData);      \
+    TypeRecordKind RK = static_cast<TypeRecordKind>(LeafEnum);                 \
+    auto Result = ClassName::deserialize(RK, FieldData);                       \
+    if (Result.getError())                                                     \
+      return parseError();                                                     \
+    static_cast<Derived *>(this)->visit##ClassName(Leaf, *Result);             \
     break;                                                                     \
   }
 #include "TypeRecords.def"

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h Wed May 11 12:47:35 2016
@@ -423,9 +423,10 @@ enum class TypeRecordKind : uint16_t {
   Alias = 0x150a,
   Member = 0x150d,
   StaticMember = 0x150e,
-  Method = 0x150f,
+  OverloadedMethod = 0x150f,
   NestedType = 0x1510,
   OneMethod = 0x1511,
+  TypeServer2 = 0x1515,
   VirtualFunctionTable = 0x151d,
 
   FunctionId = 0x1601,

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=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h Wed May 11 12:47:35 2016
@@ -10,11 +10,14 @@
 #ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
 #define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H
 
+#include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/ErrorOr.h"
 #include <cinttypes>
+#include <tuple>
 
 namespace llvm {
 namespace codeview {
@@ -23,6 +26,155 @@ using llvm::support::little32_t;
 using llvm::support::ulittle16_t;
 using llvm::support::ulittle32_t;
 
+/// Decodes a numeric "leaf" value. These are integer literals encountered in
+/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
+/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
+/// that indicates the bitwidth and sign of the numeric data.
+bool decodeNumericLeaf(ArrayRef<uint8_t> &Data, APSInt &Num);
+
+inline bool decodeNumericLeaf(StringRef &Data, APSInt &Num) {
+  ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
+                          Data.size());
+  bool Success = decodeNumericLeaf(Bytes, Num);
+  Data = StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
+  return Success;
+}
+
+/// Decode a numeric leaf value that is known to be a uint32_t.
+bool decodeUIntLeaf(ArrayRef<uint8_t> &Data, uint64_t &Num);
+
+/// Reinterpret a byte array as an array of characters. Does not interpret as
+/// a C string, as StringRef has several helpers (split) that make that easy.
+inline StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
+  return StringRef(reinterpret_cast<const char *>(LeafData.data()),
+                   LeafData.size());
+}
+
+inline StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData) {
+  return getBytesAsCharacters(LeafData).split('\0').first;
+}
+
+/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if
+/// there are not enough bytes remaining. Reinterprets the consumed bytes as a
+/// T object and points 'Res' at them.
+template <typename T, typename U>
+inline std::error_code consumeObject(U &Data, const T *&Res) {
+  if (Data.size() < sizeof(*Res))
+    return std::make_error_code(std::errc::illegal_byte_sequence);
+  Res = reinterpret_cast<const T *>(Data.data());
+  Data = Data.drop_front(sizeof(*Res));
+  return std::error_code();
+}
+
+inline std::error_code consumeCString(ArrayRef<uint8_t> &Data, StringRef &Str) {
+  if (Data.empty())
+    return std::make_error_code(std::errc::illegal_byte_sequence);
+
+  StringRef Rest;
+  std::tie(Str, Rest) = getBytesAsCharacters(Data).split('\0');
+  // We expect this to be null terminated.  If it was not, it is an error.
+  if (Data.size() == Str.size())
+    return std::make_error_code(std::errc::illegal_byte_sequence);
+
+  Data = ArrayRef<uint8_t>(Rest.bytes_begin(), Rest.bytes_end());
+  return std::error_code();
+}
+
+template <typename T>
+inline std::error_code consumeArray(ArrayRef<uint8_t> &Data,
+                                    ArrayRef<T> &Result, uint32_t N) {
+  uint32_t Size = sizeof(T) * N;
+  if (Data.size() < Size)
+    return std::make_error_code(std::errc::illegal_byte_sequence);
+
+  Result = ArrayRef<T>(reinterpret_cast<const T *>(Data.data()), N);
+  Data = Data.drop_front(Size);
+  return std::error_code();
+}
+
+inline std::error_code consumeUInt32(StringRef &Data, uint32_t &Res) {
+  const support::ulittle32_t *IntPtr;
+  if (auto EC = consumeObject(Data, IntPtr))
+    return EC;
+  Res = *IntPtr;
+  return std::error_code();
+}
+
+/// Equvalent to CV_fldattr_t in cvinfo.h.
+struct MemberAttributes {
+  ulittle16_t Attrs;
+
+  /// Get the access specifier. Valid for any kind of member.
+  MemberAccess getAccess() const {
+    return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
+  }
+
+  /// Indicates if a method is defined with friend, virtual, static, etc.
+  MethodKind getMethodKind() const {
+    return MethodKind(
+        (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >> 2);
+  }
+
+  /// Get the flags that are not included in access control or method
+  /// properties.
+  MethodOptions getFlags() const {
+    return MethodOptions(
+        unsigned(Attrs) &
+        ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
+  }
+
+  /// Is this method virtual.
+  bool isVirtual() const {
+    auto MP = getMethodKind();
+    return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
+           MP != MethodKind::Static;
+  }
+
+  /// Does this member introduce a new virtual method.
+  bool isIntroducedVirtual() const {
+    auto MP = getMethodKind();
+    return MP == MethodKind::IntroducingVirtual ||
+           MP == MethodKind::PureIntroducingVirtual;
+  }
+};
+
+// Does not correspond to any tag, this is the tail of an LF_POINTER record
+// if it represents a member pointer.
+class MemberPointerInfo {
+public:
+  MemberPointerInfo() {}
+
+  MemberPointerInfo(TypeIndex ContainingType,
+                    PointerToMemberRepresentation Representation)
+      : ContainingType(ContainingType), Representation(Representation) {}
+
+  static ErrorOr<MemberPointerInfo> deserialize(ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    TypeIndex T = L->ClassType;
+    uint16_t R = L->Representation;
+    PointerToMemberRepresentation PMR =
+        static_cast<PointerToMemberRepresentation>(R);
+    return MemberPointerInfo(T, PMR);
+  }
+
+  TypeIndex getContainingType() const { return ContainingType; }
+  PointerToMemberRepresentation getRepresentation() const {
+    return Representation;
+  }
+
+private:
+  struct Layout {
+    TypeIndex ClassType;
+    ulittle16_t Representation; // PointerToMemberRepresentation
+  };
+
+  TypeIndex ContainingType;
+  PointerToMemberRepresentation Representation;
+};
+
 class TypeRecord {
 protected:
   explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {}
@@ -34,20 +186,39 @@ private:
   TypeRecordKind Kind;
 };
 
+// LF_MODIFIER
 class ModifierRecord : public TypeRecord {
 public:
-  ModifierRecord(TypeIndex ModifiedType, ModifierOptions Options)
+  ModifierRecord(TypeIndex ModifiedType, ModifierOptions Modifiers)
       : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType),
-        Options(Options) {}
+        Modifiers(Modifiers) {}
+
+  static ErrorOr<ModifierRecord> deserialize(TypeRecordKind Kind,
+                                             ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    TypeIndex M = L->ModifiedType;
+    uint16_t O = L->Modifiers;
+    ModifierOptions MO = static_cast<ModifierOptions>(O);
+    return ModifierRecord(M, MO);
+  }
 
   TypeIndex getModifiedType() const { return ModifiedType; }
-  ModifierOptions getOptions() const { return Options; }
+  ModifierOptions getModifiers() const { return Modifiers; }
 
 private:
+  struct Layout {
+    TypeIndex ModifiedType;
+    ulittle16_t Modifiers; // ModifierOptions
+  };
+
   TypeIndex ModifiedType;
-  ModifierOptions Options;
+  ModifierOptions Modifiers;
 };
 
+// LF_PROCEDURE
 class ProcedureRecord : public TypeRecord {
 public:
   ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv,
@@ -57,6 +228,18 @@ public:
         CallConv(CallConv), Options(Options), ParameterCount(ParameterCount),
         ArgumentList(ArgumentList) {}
 
+  static ErrorOr<ProcedureRecord> deserialize(TypeRecordKind Kind,
+                                              ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    return ProcedureRecord(L->ReturnType, L->CallConv, L->Options,
+                           L->NumParameters, L->ArgListType);
+  }
+
+  static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
+
   TypeIndex getReturnType() const { return ReturnType; }
   CallingConvention getCallConv() const { return CallConv; }
   FunctionOptions getOptions() const { return Options; }
@@ -64,6 +247,14 @@ public:
   TypeIndex getArgumentList() const { return ArgumentList; }
 
 private:
+  struct Layout {
+    TypeIndex ReturnType;
+    CallingConvention CallConv;
+    FunctionOptions Options;
+    ulittle16_t NumParameters;
+    TypeIndex ArgListType;
+  };
+
   TypeIndex ReturnType;
   CallingConvention CallConv;
   FunctionOptions Options;
@@ -71,6 +262,7 @@ private:
   TypeIndex ArgumentList;
 };
 
+// LF_MFUNCTION
 class MemberFunctionRecord : public TypeRecord {
 public:
   MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType,
@@ -83,6 +275,17 @@ public:
         ArgumentList(ArgumentList),
         ThisPointerAdjustment(ThisPointerAdjustment) {}
 
+  static ErrorOr<MemberFunctionRecord> deserialize(TypeRecordKind Kind,
+                                                   ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    return MemberFunctionRecord(L->ReturnType, L->ClassType, L->ThisType,
+                                L->CallConv, L->Options, L->NumParameters,
+                                L->ArgListType, L->ThisAdjustment);
+  }
+
   TypeIndex getReturnType() const { return ReturnType; }
   TypeIndex getClassType() const { return ClassType; }
   TypeIndex getThisType() const { return ThisType; }
@@ -93,6 +296,17 @@ public:
   int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; }
 
 private:
+  struct Layout {
+    TypeIndex ReturnType;
+    TypeIndex ClassType;
+    TypeIndex ThisType;
+    CallingConvention CallConv;
+    FunctionOptions Options;
+    ulittle16_t NumParameters;
+    TypeIndex ArgListType;
+    little32_t ThisAdjustment;
+  };
+
   TypeIndex ReturnType;
   TypeIndex ClassType;
   TypeIndex ThisType;
@@ -103,78 +317,253 @@ private:
   int32_t ThisPointerAdjustment;
 };
 
-class ArgumentListRecord : public TypeRecord {
+// LF_MFUNC_ID
+class MemberFunctionIdRecord : public TypeRecord {
 public:
-  explicit ArgumentListRecord(llvm::ArrayRef<TypeIndex> ArgumentTypes)
-      : TypeRecord(TypeRecordKind::ArgumentList), ArgumentTypes(ArgumentTypes) {
+  MemberFunctionIdRecord(TypeIndex ClassType, TypeIndex FunctionType,
+                         StringRef Name)
+      : TypeRecord(TypeRecordKind::MemberFunctionId), ClassType(ClassType),
+        FunctionType(FunctionType), Name(Name) {}
+
+  static ErrorOr<MemberFunctionIdRecord> deserialize(TypeRecordKind Kind,
+                                                     ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    return MemberFunctionIdRecord(L->ClassType, L->FunctionType, Name);
   }
 
-  llvm::ArrayRef<TypeIndex> getArgumentTypes() const { return ArgumentTypes; }
+  TypeIndex getClassType() const { return ClassType; }
+  TypeIndex getFunctionType() const { return FunctionType; }
+  StringRef getName() const { return Name; }
 
 private:
-  llvm::ArrayRef<TypeIndex> ArgumentTypes;
+  struct Layout {
+    TypeIndex ClassType;
+    TypeIndex FunctionType;
+    // Name: The null-terminated name follows.
+  };
+  TypeIndex ClassType;
+  TypeIndex FunctionType;
+  StringRef Name;
 };
 
-class PointerRecordBase : public TypeRecord {
+// LF_ARGLIST, LF_SUBSTR_LIST
+class StringListRecord : public TypeRecord {
 public:
-  PointerRecordBase(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
-                    PointerOptions Options, uint8_t Size)
+  StringListRecord(TypeRecordKind Kind, ArrayRef<TypeIndex> Indices)
+      : TypeRecord(Kind), StringIndices(Indices) {}
+
+  static ErrorOr<StringListRecord> deserialize(TypeRecordKind Kind,
+                                               ArrayRef<uint8_t> &Data) {
+    if (Kind != TypeRecordKind::SubstringList &&
+        Kind != TypeRecordKind::ArgumentList)
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    ArrayRef<TypeIndex> Indices;
+    if (auto EC = consumeArray(Data, Indices, L->NumArgs))
+      return EC;
+    return StringListRecord(Kind, Indices);
+  }
+
+  ArrayRef<TypeIndex> getIndices() const { return StringIndices; }
+
+  static uint32_t getLayoutSize() { return 2 + sizeof(Layout); }
+
+private:
+  struct Layout {
+    ulittle32_t NumArgs; // Number of arguments
+                         // ArgTypes[]: Type indicies of arguments
+  };
+
+  ArrayRef<TypeIndex> StringIndices;
+};
+
+// LF_POINTER
+class PointerRecord : public TypeRecord {
+public:
+  static const uint32_t PointerKindShift = 0;
+  static const uint32_t PointerKindMask = 0x1F;
+
+  static const uint32_t PointerModeShift = 5;
+  static const uint32_t PointerModeMask = 0x07;
+
+  static const uint32_t PointerSizeShift = 13;
+  static const uint32_t PointerSizeMask = 0xFF;
+
+  PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
+                PointerOptions Options, uint8_t Size)
+      : PointerRecord(ReferentType, Kind, Mode, Options, Size,
+                      MemberPointerInfo()) {}
+
+  PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
+                PointerOptions Options, uint8_t Size,
+                const MemberPointerInfo &Member)
       : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType),
-        PtrKind(Kind), Mode(Mode), Options(Options), Size(Size) {}
+        PtrKind(Kind), Mode(Mode), Options(Options), Size(Size),
+        MemberInfo(Member) {}
+
+  static ErrorOr<PointerRecord> deserialize(TypeRecordKind Kind,
+                                            ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return 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()) {
+      auto E = MemberPointerInfo::deserialize(Data);
+      if (E.getError())
+        return std::make_error_code(std::errc::illegal_byte_sequence);
+      return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size, *E);
+    }
+
+    return PointerRecord(L->PointeeType, PtrKind, Mode, Options, Size);
+  }
 
   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; }
+  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));
+  }
+  bool isVolatile() const {
+    return !!(uint32_t(Options) & uint32_t(PointerOptions::Volatile));
+  }
+  bool isUnaligned() const {
+    return !!(uint32_t(Options) & uint32_t(PointerOptions::Unaligned));
+  }
 
 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();
+    }
+  };
+
   TypeIndex ReferentType;
   PointerKind PtrKind;
   PointerMode Mode;
   PointerOptions Options;
   uint8_t Size;
+  MemberPointerInfo MemberInfo;
 };
 
-class PointerRecord : public PointerRecordBase {
-public:
-  PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode,
-                PointerOptions Options, uint8_t Size)
-      : PointerRecordBase(ReferentType, Kind, Mode, Options, Size) {}
-};
-
-class PointerToMemberRecord : public PointerRecordBase {
+// LF_NESTTYPE
+class NestedTypeRecord : public TypeRecord {
 public:
-  PointerToMemberRecord(TypeIndex ReferentType, PointerKind Kind,
-                        PointerMode Mode, PointerOptions Options, uint8_t Size,
-                        TypeIndex ContainingType,
-                        PointerToMemberRepresentation Representation)
-      : PointerRecordBase(ReferentType, Kind, Mode, Options, Size),
-        ContainingType(ContainingType), Representation(Representation) {}
+  NestedTypeRecord(TypeIndex Type, StringRef Name)
+      : TypeRecord(TypeRecordKind::NestedType), Type(Type), Name(Name) {}
 
-  TypeIndex getContainingType() const { return ContainingType; }
-  PointerToMemberRepresentation getRepresentation() const {
-    return Representation;
+  static ErrorOr<NestedTypeRecord> deserialize(TypeRecordKind Kind,
+                                               ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    return NestedTypeRecord(L->Type, Name);
   }
 
+  TypeIndex getNestedType() const { return Type; }
+  StringRef getName() const { return Name; }
+
 private:
-  TypeIndex ContainingType;
-  PointerToMemberRepresentation Representation;
+  struct Layout {
+    ulittle16_t Pad0; // Should be zero
+    TypeIndex Type;   // Type index of nested type
+                      // Name: Null-terminated string
+  };
+
+  TypeIndex Type;
+  StringRef Name;
 };
 
+// LF_ARRAY
 class ArrayRecord : public TypeRecord {
 public:
   ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size,
-              llvm::StringRef Name)
+              StringRef Name)
       : TypeRecord(TypeRecordKind::Array), ElementType(ElementType),
         IndexType(IndexType), Size(Size), Name(Name) {}
 
+  static ErrorOr<ArrayRecord> deserialize(TypeRecordKind Kind,
+                                          ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    uint64_t Size;
+    if (!decodeUIntLeaf(Data, Size))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    return ArrayRecord(L->ElementType, L->IndexType, Size, Name);
+  }
+
   TypeIndex getElementType() const { return ElementType; }
   TypeIndex getIndexType() const { return IndexType; }
   uint64_t getSize() const { return Size; }
   llvm::StringRef getName() const { return Name; }
 
 private:
+  struct Layout {
+    TypeIndex ElementType;
+    TypeIndex IndexType;
+    // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!
+    // Name: The null-terminated name follows.
+  };
+
   TypeIndex ElementType;
   TypeIndex IndexType;
   uint64_t Size;
@@ -189,6 +578,11 @@ protected:
         FieldList(FieldList), Name(Name), UniqueName(UniqueName) {}
 
 public:
+  static const int HfaKindShift = 11;
+  static const int HfaKindMask = 0x1800;
+  static const int WinRTKindShift = 14;
+  static const int WinRTKindMask = 0xC000;
+
   uint16_t getMemberCount() const { return MemberCount; }
   ClassOptions getOptions() const { return Options; }
   TypeIndex getFieldList() const { return FieldList; }
@@ -203,17 +597,48 @@ private:
   StringRef UniqueName;
 };
 
-class AggregateRecord : public TagRecord {
+// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
+class ClassRecord : public TagRecord {
 public:
-  AggregateRecord(TypeRecordKind Kind, uint16_t MemberCount,
-                  ClassOptions Options, HfaKind Hfa,
-                  WindowsRTClassKind WinRTKind, TypeIndex FieldList,
-                  TypeIndex DerivationList, TypeIndex VTableShape,
-                  uint64_t Size, StringRef Name, StringRef UniqueName)
+  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)
       : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName),
         Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList),
         VTableShape(VTableShape), Size(Size) {}
 
+  static ErrorOr<ClassRecord> deserialize(TypeRecordKind Kind,
+                                          ArrayRef<uint8_t> &Data) {
+    uint64_t Size = 0;
+    StringRef Name;
+    StringRef UniqueName;
+    uint16_t Props;
+
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    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);
+
+    if (!decodeUIntLeaf(Data, Size))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    if (Props & uint16_t(ClassOptions::HasUniqueName)) {
+      if (auto EC = consumeCString(Data, UniqueName))
+        return EC;
+    }
+
+    ClassOptions Options = static_cast<ClassOptions>(Props);
+    return ClassRecord(Kind, L->MemberCount, Options, Hfa, WRT, L->FieldList,
+                       L->DerivedFrom, L->VShape, Size, Name, UniqueName);
+  }
+
   HfaKind getHfa() const { return Hfa; }
   WindowsRTClassKind getWinRTKind() const { return WinRTKind; }
   TypeIndex getDerivationList() const { return DerivationList; }
@@ -221,6 +646,17 @@ public:
   uint64_t getSize() const { return 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.
+  };
+
   HfaKind Hfa;
   WindowsRTClassKind WinRTKind;
   TypeIndex DerivationList;
@@ -228,6 +664,63 @@ private:
   uint64_t Size;
 };
 
+// LF_UNION
+struct UnionRecord : public TagRecord {
+  UnionRecord(uint16_t MemberCount, ClassOptions Options, HfaKind Hfa,
+              TypeIndex FieldList, uint64_t Size, StringRef Name,
+              StringRef UniqueName)
+      : TagRecord(TypeRecordKind::Union, MemberCount, Options, FieldList, Name,
+                  UniqueName),
+        Hfa(Hfa), Size(Size) {}
+
+  static ErrorOr<UnionRecord> deserialize(TypeRecordKind Kind,
+                                          ArrayRef<uint8_t> &Data) {
+    uint64_t Size = 0;
+    StringRef Name;
+    StringRef UniqueName;
+    uint16_t Props;
+
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    Props = L->Properties;
+
+    uint16_t HfaMask = (Props & HfaKindMask) >> HfaKindShift;
+    HfaKind Hfa = static_cast<HfaKind>(HfaMask);
+
+    if (!decodeUIntLeaf(Data, Size))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    if (Props & uint16_t(ClassOptions::HasUniqueName)) {
+      if (auto EC = consumeCString(Data, UniqueName))
+        return EC;
+    }
+
+    ClassOptions Options = static_cast<ClassOptions>(Props);
+    return UnionRecord(L->MemberCount, Options, Hfa, L->FieldList, Size, Name,
+                       UniqueName);
+  }
+
+  HfaKind getHfa() const { return Hfa; }
+  uint64_t getSize() const { return 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.
+  };
+
+  HfaKind Hfa;
+  uint64_t Size;
+};
+
+// LF_ENUM
 class EnumRecord : public TagRecord {
 public:
   EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList,
@@ -236,9 +729,32 @@ public:
                   UniqueName),
         UnderlyingType(UnderlyingType) {}
 
+  static ErrorOr<EnumRecord> deserialize(TypeRecordKind Kind,
+                                         ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    uint16_t P = L->Properties;
+    ClassOptions Options = static_cast<ClassOptions>(P);
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    return EnumRecord(L->NumEnumerators, Options, L->FieldListType, Name, Name,
+                      L->UnderlyingType);
+  }
+
   TypeIndex getUnderlyingType() const { return UnderlyingType; }
 
 private:
+  struct Layout {
+    ulittle16_t NumEnumerators; // Number of enumerators
+    ulittle16_t Properties;
+    TypeIndex UnderlyingType;
+    TypeIndex FieldListType;
+    // Name: The null-terminated name follows.
+  };
+
   TypeIndex UnderlyingType;
 };
 
@@ -258,311 +774,668 @@ private:
   uint8_t BitOffset;
 };
 
+// LF_VTSHAPE
 class VirtualTableShapeRecord : TypeRecord {
 public:
   explicit VirtualTableShapeRecord(ArrayRef<VirtualTableSlotKind> Slots)
+      : TypeRecord(TypeRecordKind::VirtualTableShape), SlotsRef(Slots) {}
+  explicit VirtualTableShapeRecord(std::vector<VirtualTableSlotKind> Slots)
       : TypeRecord(TypeRecordKind::VirtualTableShape), Slots(Slots) {}
 
-  ArrayRef<VirtualTableSlotKind> getSlots() const { return Slots; }
+  static ErrorOr<VirtualTableShapeRecord> deserialize(TypeRecordKind Kind,
+                                                      ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    std::vector<VirtualTableSlotKind> Slots;
+    uint16_t Count = L->VFEntryCount;
+    while (Count > 0) {
+      if (Data.empty())
+        return std::make_error_code(std::errc::illegal_byte_sequence);
+
+      // Process up to 2 nibbles at a time (if there are at least 2 remaining)
+      uint8_t Value = Data[0] & 0x0F;
+      Slots.push_back(static_cast<VirtualTableSlotKind>(Value));
+      if (--Count > 0) {
+        Value = (Data[0] & 0xF0) >> 4;
+        Slots.push_back(static_cast<VirtualTableSlotKind>(Value));
+        --Count;
+      }
+      Data = Data.slice(1);
+    }
 
-private:
-  ArrayRef<VirtualTableSlotKind> Slots;
-};
+    return VirtualTableShapeRecord(Slots);
+  }
 
-//===----------------------------------------------------------------------===//
-// On-disk representation of type information
+  ArrayRef<VirtualTableSlotKind> getSlots() const {
+    if (!SlotsRef.empty())
+      return SlotsRef;
+    return Slots;
+  }
+  uint32_t getEntryCount() const { return getSlots().size(); }
 
-// A CodeView type stream is a sequence of TypeRecords. Records larger than
-// 65536 must chain on to a second record. Each TypeRecord is followed by one of
-// the leaf types described below.
+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
-struct TypeServer2 {
-  char Signature[16];  // GUID
-  ulittle32_t Age;
-  // Name: Name of the PDB as a null-terminated string
+private:
+  ArrayRef<VirtualTableSlotKind> SlotsRef;
+  std::vector<VirtualTableSlotKind> Slots;
 };
 
-// LF_STRING_ID
-struct StringId {
-  TypeIndex id;
-};
+// LF_TYPESERVER2
+class TypeServer2Record : TypeRecord {
+public:
+  TypeServer2Record(StringRef Guid, uint32_t Age, StringRef Name)
+      : TypeRecord(TypeRecordKind::TypeServer2), Guid(Guid), Age(Age),
+        Name(Name) {}
+
+  static ErrorOr<TypeServer2Record> deserialize(TypeRecordKind Kind,
+                                                ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    return TypeServer2Record(StringRef(L->Guid, 16), L->Age, Name);
+  }
 
-// LF_FUNC_ID
-struct FuncId {
-  TypeIndex ParentScope;
-  TypeIndex FunctionType;
-  // Name: The null-terminated name follows.
-};
+  StringRef getGuid() const { return Guid; }
 
-// LF_CLASS, LF_STRUCTURE, LF_INTERFACE
-struct ClassType {
-  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.
-};
+  uint32_t getAge() const { return Age; }
 
-// LF_UNION
-struct UnionType {
-  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.
+  StringRef getName() const { return Name; }
+
+private:
+  struct Layout {
+    char Guid[16]; // GUID
+    ulittle32_t Age;
+    // Name: Name of the PDB as a null-terminated string
+  };
+
+  StringRef Guid;
+  uint32_t Age;
+  StringRef Name;
 };
 
-// LF_POINTER
-struct PointerType {
-  TypeIndex PointeeType;
-  ulittle32_t Attrs; // pointer attributes
-  // if pointer to member:
-  //   PointerToMemberTail
-
-  PointerKind getPtrKind() const { return PointerKind(Attrs & 0x1f); }
-  PointerMode getPtrMode() const { return PointerMode((Attrs >> 5) & 0x07); }
-  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); }
+// LF_STRING_ID
+class StringIdRecord : public TypeRecord {
+public:
+  StringIdRecord(TypeIndex Id, StringRef String)
+      : TypeRecord(TypeRecordKind::StringId), Id(Id), String(String) {}
 
-  bool isPointerToDataMember() const {
-    return getPtrMode() == PointerMode::PointerToDataMember;
+  static ErrorOr<StringIdRecord> deserialize(TypeRecordKind Kind,
+                                             ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+    return StringIdRecord(L->id, Name);
   }
-  bool isPointerToMemberFunction() const {
-    return getPtrMode() == PointerMode::PointerToMemberFunction;
-  }
-  bool isPointerToMember() const {
-    return isPointerToMemberFunction() || isPointerToDataMember();
-  }
-};
 
-struct PointerToMemberTail {
-  TypeIndex ClassType;
-  ulittle16_t Representation; // PointerToMemberRepresentation
-};
+  TypeIndex getId() const { return Id; }
 
-/// In Clang parlance, these are "qualifiers".  LF_MODIFIER
-struct TypeModifier {
-  TypeIndex ModifiedType;
-  ulittle16_t Modifiers; // ModifierOptions
-};
+  StringRef getString() const { return String; }
 
-// LF_VTSHAPE
-struct VTableShape {
-  // 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.
-};
+private:
+  struct Layout {
+    TypeIndex id;
+    // Name: Name of the PDB as a null-terminated string
+  };
 
-// LF_UDT_SRC_LINE
-struct UDTSrcLine {
-  TypeIndex UDT;        // The user-defined type
-  TypeIndex SourceFile; // StringID containing the source filename
-  ulittle32_t LineNumber;
+  TypeIndex Id;
+  StringRef String;
 };
 
-// LF_ARGLIST, LF_SUBSTR_LIST
-struct ArgList {
-  ulittle32_t NumArgs; // Number of arguments
-  // ArgTypes[]: Type indicies of arguments
-};
+// LF_FUNC_ID
+class FuncIdRecord : public TypeRecord {
+public:
+  FuncIdRecord(TypeIndex ParentScope, TypeIndex FunctionType, StringRef Name)
+      : TypeRecord(TypeRecordKind::FunctionId), ParentScope(ParentScope),
+        FunctionType(FunctionType), Name(Name) {}
+
+  static ErrorOr<FuncIdRecord> deserialize(TypeRecordKind Kind,
+                                           ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
 
-// LF_BUILDINFO
-struct BuildInfo {
-  ulittle16_t NumArgs; // Number of arguments
-  // ArgTypes[]: Type indicies of arguments
-};
+    return FuncIdRecord(L->ParentScope, L->FunctionType, Name);
+  }
 
-// LF_ENUM
-struct EnumType {
-  ulittle16_t NumEnumerators; // Number of enumerators
-  ulittle16_t Properties;
-  TypeIndex UnderlyingType;
-  TypeIndex FieldListType;
-  // Name: The null-terminated name follows.
-};
+  TypeIndex getParentScope() const { return ParentScope; }
 
-// LF_ARRAY
-struct ArrayType {
-  TypeIndex ElementType;
-  TypeIndex IndexType;
-  // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!
-  // Name: The null-terminated name follows.
-};
+  TypeIndex getFunctionType() const { return FunctionType; }
 
-// LF_VFTABLE
-struct VFTableType {
-  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.
-};
+  StringRef getName() const { return Name; }
 
-// LF_MFUNC_ID
-struct MemberFuncId {
-  TypeIndex ClassType;
+private:
+  struct Layout {
+    TypeIndex ParentScope;
+    TypeIndex FunctionType;
+    // Name: The null-terminated name follows.
+  };
+
+  TypeIndex ParentScope;
   TypeIndex FunctionType;
-  // Name: The null-terminated name follows.
+  StringRef Name;
 };
 
-// LF_PROCEDURE
-struct ProcedureType {
-  TypeIndex ReturnType;
-  CallingConvention CallConv;
-  FunctionOptions Options;
-  ulittle16_t NumParameters;
-  TypeIndex ArgListType;
-};
+// LF_UDT_SRC_LINE
+class UdtSourceLineRecord : public TypeRecord {
+public:
+  UdtSourceLineRecord(TypeIndex UDT, TypeIndex SourceFile, uint32_t LineNumber)
+      : TypeRecord(TypeRecordKind::UdtSourceLine), UDT(UDT),
+        SourceFile(SourceFile), LineNumber(LineNumber) {}
+
+  static ErrorOr<UdtSourceLineRecord> deserialize(TypeRecordKind Kind,
+                                                  ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
 
-// LF_MFUNCTION
-struct MemberFunctionType {
-  TypeIndex ReturnType;
-  TypeIndex ClassType;
-  TypeIndex ThisType;
-  CallingConvention CallConv;
-  FunctionOptions Options;
-  ulittle16_t NumParameters;
-  TypeIndex ArgListType;
-  little32_t ThisAdjustment;
-};
+    return UdtSourceLineRecord(L->UDT, L->SourceFile, L->LineNumber);
+  }
 
-//===----------------------------------------------------------------------===//
-// Field list records, which do not include leafs or sizes
+  TypeIndex getUDT() const { return UDT; }
+  TypeIndex getSourceFile() const { return SourceFile; }
+  uint32_t getLineNumber() const { return LineNumber; }
 
-/// Equvalent to CV_fldattr_t in cvinfo.h.
-struct MemberAttributes {
-  ulittle16_t Attrs;
+private:
+  struct Layout {
+    TypeIndex UDT;        // The user-defined type
+    TypeIndex SourceFile; // StringID containing the source filename
+    ulittle32_t LineNumber;
+  };
+
+  TypeIndex UDT;
+  TypeIndex SourceFile;
+  uint32_t LineNumber;
+};
 
-  /// Get the access specifier. Valid for any kind of member.
-  MemberAccess getAccess() const {
-    return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
-  }
+// LF_BUILDINFO
+class BuildInfoRecord : public TypeRecord {
+public:
+  BuildInfoRecord(ArrayRef<TypeIndex> ArgIndices)
+      : TypeRecord(TypeRecordKind::Modifier), ArgIndices(ArgIndices) {}
 
-  /// Indicates if a method is defined with friend, virtual, static, etc.
-  MethodKind getMethodKind() const {
-    return MethodKind(
-        (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >> 2);
+  static ErrorOr<BuildInfoRecord> deserialize(TypeRecordKind Kind,
+                                              ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    ArrayRef<TypeIndex> Indices;
+    if (auto EC = consumeArray(Data, Indices, L->NumArgs))
+      return EC;
+    return BuildInfoRecord(Indices);
   }
 
-  /// Get the flags that are not included in access control or method
-  /// properties.
-  MethodOptions getFlags() const {
-    return MethodOptions(
-        unsigned(Attrs) &
-        ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
-  }
+  ArrayRef<TypeIndex> getArgs() const { return ArgIndices; }
 
-  /// Is this method virtual.
-  bool isVirtual() const {
-    auto MP = getMethodKind();
-    return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
-           MP != MethodKind::Static;
+private:
+  struct Layout {
+    ulittle16_t NumArgs; // Number of arguments
+                         // ArgTypes[]: Type indicies of arguments
+  };
+  ArrayRef<TypeIndex> ArgIndices;
+};
+
+// LF_VFTABLE
+class VirtualTableRecord : public TypeRecord {
+public:
+  VirtualTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
+                     uint32_t VFPtrOffset, StringRef Name,
+                     ArrayRef<StringRef> Methods)
+      : TypeRecord(TypeRecordKind::VirtualFunctionTable),
+        CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
+        VFPtrOffset(VFPtrOffset), Name(Name), MethodNamesRef(Methods) {}
+  VirtualTableRecord(TypeIndex CompleteClass, TypeIndex OverriddenVFTable,
+                     uint32_t VFPtrOffset, StringRef Name,
+                     const std::vector<StringRef> &Methods)
+      : TypeRecord(TypeRecordKind::VirtualFunctionTable),
+        CompleteClass(CompleteClass), OverriddenVFTable(OverriddenVFTable),
+        VFPtrOffset(VFPtrOffset), Name(Name), MethodNames(Methods) {}
+
+  static ErrorOr<VirtualTableRecord> deserialize(TypeRecordKind Kind,
+                                                 ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+
+    std::vector<StringRef> Names;
+    while (!Data.empty()) {
+      if (auto EC = consumeCString(Data, Name))
+        return EC;
+      Names.push_back(Name);
+    }
+    return VirtualTableRecord(L->CompleteClass, L->OverriddenVFTable,
+                              L->VFPtrOffset, Name, Names);
   }
 
-  /// Does this member introduce a new virtual method.
-  bool isIntroducedVirtual() const {
-    auto MP = getMethodKind();
-    return MP == MethodKind::IntroducingVirtual ||
-           MP == MethodKind::PureIntroducingVirtual;
+  TypeIndex getCompleteClass() const { return CompleteClass; }
+  TypeIndex getOverriddenVTable() const { return OverriddenVFTable; }
+  uint32_t getVFPtrOffset() const { return VFPtrOffset; }
+  StringRef getName() const { return Name; }
+  ArrayRef<StringRef> getMethodNames() const {
+    if (!MethodNamesRef.empty())
+      return MethodNamesRef;
+    return MethodNames;
   }
-};
 
-// LF_NESTTYPE
-struct NestedType {
-  ulittle16_t Pad0; // Should be zero
-  TypeIndex Type;   // Type index of nested type
-  // Name: Null-terminated string
+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.
+  };
+
+  TypeIndex CompleteClass;
+  TypeIndex OverriddenVFTable;
+  ulittle32_t VFPtrOffset;
+  StringRef Name;
+  ArrayRef<StringRef> MethodNamesRef;
+  std::vector<StringRef> MethodNames;
 };
 
 // LF_ONEMETHOD
-struct OneMethod {
-  MemberAttributes Attrs;
-  TypeIndex Type;
-  // If is introduced virtual method:
-  //   VFTableOffset: int32_t offset in vftable
-  // Name: Null-terminated string
+class OneMethodRecord : public TypeRecord {
+public:
+  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) {}
+
+  static ErrorOr<OneMethodRecord> deserialize(TypeRecordKind Kind,
+                                              ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    MethodOptions Options = L->Attrs.getFlags();
+    MethodKind MethKind = L->Attrs.getMethodKind();
+    MemberAccess Access = L->Attrs.getAccess();
+    int32_t VFTableOffset = 0;
+    if (L->Attrs.isIntroducedVirtual()) {
+      const little32_t *L;
+      if (consumeObject(Data, L))
+        return std::make_error_code(std::errc::illegal_byte_sequence);
+      VFTableOffset = *L;
+    }
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
 
-  MethodKind getMethodKind() const {
-    return Attrs.getMethodKind();
+    return OneMethodRecord(L->Type, MethKind, Options, Access, VFTableOffset,
+                           Name);
   }
 
-  bool isVirtual() const { return Attrs.isVirtual(); }
-  bool isIntroducedVirtual() const { return Attrs.isIntroducedVirtual(); }
-};
+  TypeIndex getType() const { return Type; }
+  MethodKind getKind() const { return Kind; }
+  MethodOptions getOptions() const { return Options; }
+  MemberAccess getAccess() const { return Access; }
+  int32_t getVFTableOffset() const { return VFTableOffset; }
+  StringRef getName() const { return Name; }
 
-// LF_METHODLIST
-struct MethodListEntry {
-  MemberAttributes Attrs;
-  ulittle16_t Padding;
+  bool isIntroducingVirtual() const {
+    const uint8_t K = static_cast<uint8_t>(Kind);
+    const uint8_t V = static_cast<uint8_t>(MethodKind::IntroducingVirtual);
+    const uint8_t PV = static_cast<uint8_t>(MethodKind::PureIntroducingVirtual);
+    return (K & V) || (K & PV);
+  }
+
+private:
+  struct Layout {
+    MemberAttributes Attrs;
+    TypeIndex Type;
+    // If is introduced virtual method:
+    //   VFTableOffset: int32_t offset in vftable
+    // Name: Null-terminated string
+  };
 
   TypeIndex Type;
-  // If is introduced virtual method:
-  //   VFTableOffset: int32_t offset in vftable
+  MethodKind Kind;
+  MethodOptions Options;
+  MemberAccess Access;
+  int32_t VFTableOffset;
+  StringRef Name;
+};
 
-  MethodKind getMethodKind() const {
-    return Attrs.getMethodKind();
+// LF_METHODLIST
+class MethodListRecord : public TypeRecord {
+public:
+  MethodListRecord(TypeIndex Type, MethodKind Kind, MethodOptions Options,
+                   MemberAccess Access, int32_t VFTableOffset)
+      : TypeRecord(TypeRecordKind::MethodList), Type(Type), Kind(Kind),
+        Options(Options), Access(Access), VFTableOffset(VFTableOffset) {}
+
+  static ErrorOr<MethodListRecord> deserialize(TypeRecordKind Kind,
+                                               ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    MethodOptions Options = L->Attrs.getFlags();
+    MethodKind MethKind = L->Attrs.getMethodKind();
+    MemberAccess Access = L->Attrs.getAccess();
+    int32_t VFTableOffset = 0;
+    if (L->Attrs.isIntroducedVirtual()) {
+      const little32_t *L;
+      if (consumeObject(Data, L))
+        return std::make_error_code(std::errc::illegal_byte_sequence);
+      VFTableOffset = *L;
+    }
+
+    return MethodListRecord(L->Type, MethKind, Options, Access, VFTableOffset);
   }
 
-  bool isVirtual() const { return Attrs.isVirtual(); }
-  bool isIntroducedVirtual() const { return Attrs.isIntroducedVirtual(); }
+  TypeIndex getType() const { return Type; }
+  MethodKind getMethodKind() const { return Kind; }
+  MethodOptions getOptions() const { return Options; }
+  MemberAccess getAccess() const { return Access; }
+  int32_t getVFTableOffset() const { return VFTableOffset; }
+
+private:
+  struct Layout {
+    MemberAttributes Attrs;
+    ulittle16_t Padding;
+
+    TypeIndex Type;
+    // If is introduced virtual method:
+    //   VFTableOffset: int32_t offset in vftable
+  };
+
+  TypeIndex Type;
+  MethodKind Kind;
+  MethodOptions Options;
+  MemberAccess Access;
+  int32_t VFTableOffset;
 };
 
 /// For method overload sets.  LF_METHOD
-struct OverloadedMethod {
-  ulittle16_t MethodCount; // Size of overload set
-  TypeIndex MethList;      // Type index of methods in overload set
-  // Name: Null-terminated string
-};
+class OverloadedMethodRecord : public TypeRecord {
+public:
+  OverloadedMethodRecord(uint16_t NumOverloads, TypeIndex MethodList,
+                         StringRef Name)
+      : TypeRecord(TypeRecordKind::OverloadedMethod),
+        NumOverloads(NumOverloads), MethodList(MethodList), Name(Name) {}
+
+  static ErrorOr<OverloadedMethodRecord> deserialize(TypeRecordKind Kind,
+                                                     ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
 
-// LF_VFUNCTAB
-struct VirtualFunctionPointer {
-  ulittle16_t Pad0;
-  TypeIndex Type;   // Type of vfptr
+    return OverloadedMethodRecord(L->MethodCount, L->MethList, Name);
+  }
+
+  uint16_t getNumOverloads() const { return NumOverloads; }
+  TypeIndex getMethodList() const { return MethodList; }
+  StringRef getName() const { return Name; }
+
+private:
+  struct Layout {
+    ulittle16_t MethodCount; // Size of overload set
+    TypeIndex MethList;      // Type index of methods in overload set
+                             // Name: Null-terminated string
+  };
+
+  uint16_t NumOverloads;
+  TypeIndex MethodList;
+  StringRef Name;
 };
 
 // LF_MEMBER
-struct DataMember {
-  MemberAttributes Attrs; // Access control attributes, etc
+class DataMemberRecord : public TypeRecord {
+public:
+  DataMemberRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset,
+                   StringRef Name)
+      : TypeRecord(TypeRecordKind::Member), Access(Access), Type(Type),
+        FieldOffset(Offset), Name(Name) {}
+
+  static ErrorOr<DataMemberRecord> deserialize(TypeRecordKind Kind,
+                                               ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    uint64_t Offset;
+    if (!decodeUIntLeaf(Data, Offset))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+
+    return DataMemberRecord(L->Attrs.getAccess(), L->Type, Offset, Name);
+  }
+
+  MemberAccess getAccess() const { return Access; }
+  TypeIndex getType() const { return Type; }
+  uint64_t getFieldOffset() const { return FieldOffset; }
+  StringRef getName() const { return Name; }
+
+private:
+  struct Layout {
+    MemberAttributes Attrs; // Access control attributes, etc
+    TypeIndex Type;
+    // FieldOffset: LF_NUMERIC encoded byte offset
+    // Name: Null-terminated string
+  };
+
+  MemberAccess Access;
   TypeIndex Type;
-  // FieldOffset: LF_NUMERIC encoded byte offset
-  // Name: Null-terminated string
+  uint64_t FieldOffset;
+  StringRef Name;
 };
 
 // LF_STMEMBER
-struct StaticDataMember {
-  MemberAttributes Attrs; // Access control attributes, etc
+class StaticDataMemberRecord : public TypeRecord {
+public:
+  StaticDataMemberRecord(MemberAccess Access, TypeIndex Type, StringRef Name)
+      : TypeRecord(TypeRecordKind::StaticMember), Access(Access), Type(Type),
+        Name(Name) {}
+
+  static ErrorOr<StaticDataMemberRecord> deserialize(TypeRecordKind Kind,
+                                                     ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+
+    return StaticDataMemberRecord(L->Attrs.getAccess(), L->Type, Name);
+  }
+
+  MemberAccess getAccess() const { return Access; }
+  TypeIndex getType() const { return Type; }
+  StringRef getName() const { return Name; }
+
+private:
+  struct Layout {
+    MemberAttributes Attrs; // Access control attributes, etc
+    TypeIndex Type;
+    // Name: Null-terminated string
+  };
+
+  MemberAccess Access;
   TypeIndex Type;
-  // Name: Null-terminated string
+  StringRef Name;
 };
 
 // LF_ENUMERATE
-struct Enumerator {
-  MemberAttributes Attrs; // Access control attributes, etc
-  // EnumValue: LF_NUMERIC encoded enumerator value
-  // Name: Null-terminated string
+class EnumeratorRecord : public TypeRecord {
+public:
+  EnumeratorRecord(MemberAccess Access, APSInt Value, StringRef Name)
+      : TypeRecord(TypeRecordKind::Enumerate), Access(Access), Value(Value),
+        Name(Name) {}
+
+  static ErrorOr<EnumeratorRecord> deserialize(TypeRecordKind Kind,
+                                               ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    if (Data.empty())
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+    APSInt Value;
+    if (!decodeNumericLeaf(Data, Value))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+
+    StringRef Name;
+    if (auto EC = consumeCString(Data, Name))
+      return EC;
+
+    return EnumeratorRecord(L->Attrs.getAccess(), Value, Name);
+  }
+
+  MemberAccess getAccess() const { return Access; }
+  APSInt getValue() const { return Value; }
+  StringRef getName() const { return Name; }
+
+private:
+  struct Layout {
+    MemberAttributes Attrs; // Access control attributes, etc
+                            // EnumValue: LF_NUMERIC encoded enumerator value
+                            // Name: Null-terminated string
+  };
+
+  MemberAccess Access;
+  APSInt Value;
+  StringRef Name;
+};
+
+// LF_VFUNCTAB
+class VirtualFunctionPointerRecord : public TypeRecord {
+public:
+  VirtualFunctionPointerRecord(TypeIndex Type)
+      : TypeRecord(TypeRecordKind::VirtualFunctionTablePointer), Type(Type) {}
+  static ErrorOr<VirtualFunctionPointerRecord>
+  deserialize(TypeRecordKind Kind, ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    return VirtualFunctionPointerRecord(L->Type);
+  }
+
+  TypeIndex getType() const { return Type; }
+
+private:
+  struct Layout {
+    ulittle16_t Pad0;
+    TypeIndex Type; // Type of vfptr
+  };
+  TypeIndex Type;
 };
 
 // LF_BCLASS, LF_BINTERFACE
-struct BaseClass {
-  MemberAttributes Attrs; // Access control attributes, etc
-  TypeIndex BaseType;     // Base class type
-  // BaseOffset: LF_NUMERIC encoded byte offset of base from derived.
+class BaseClassRecord : public TypeRecord {
+public:
+  BaseClassRecord(MemberAccess Access, TypeIndex Type, uint64_t Offset)
+      : TypeRecord(TypeRecordKind::BaseClass), Access(Access), Type(Type),
+        Offset(Offset) {}
+
+  static ErrorOr<BaseClassRecord> deserialize(TypeRecordKind Kind,
+                                              ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    uint64_t Offset;
+    if (!decodeUIntLeaf(Data, Offset))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+
+    return BaseClassRecord(L->Attrs.getAccess(), L->BaseType, Offset);
+  }
+
+  MemberAccess getAccess() const { return Access; }
+  TypeIndex getBaseType() const { return Type; }
+  uint64_t getBaseOffset() const { return 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.
+  };
+  MemberAccess Access;
+  TypeIndex Type;
+  uint64_t Offset;
 };
 
 // LF_VBCLASS, LF_IVBCLASS
-struct VirtualBaseClass {
-  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.
+class VirtualBaseClassRecord : public TypeRecord {
+public:
+  VirtualBaseClassRecord(MemberAccess Access, TypeIndex BaseType,
+                         TypeIndex VBPtrType, uint64_t Offset, uint64_t Index)
+      : TypeRecord(TypeRecordKind::VirtualBaseClass), Access(Access),
+        BaseType(BaseType), VBPtrType(VBPtrType), VBPtrOffset(Offset),
+        VTableIndex(Index) {}
+
+  static ErrorOr<VirtualBaseClassRecord> deserialize(TypeRecordKind Kind,
+                                                     ArrayRef<uint8_t> &Data) {
+    const Layout *L = nullptr;
+    if (auto EC = consumeObject(Data, L))
+      return EC;
+
+    uint64_t Offset;
+    uint64_t Index;
+    if (!decodeUIntLeaf(Data, Offset))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+    if (!decodeUIntLeaf(Data, Index))
+      return std::make_error_code(std::errc::illegal_byte_sequence);
+
+    return VirtualBaseClassRecord(L->Attrs.getAccess(), L->BaseType,
+                                  L->VBPtrType, Offset, Index);
+  }
+
+  MemberAccess getAccess() const { return Access; }
+  TypeIndex getBaseType() const { return BaseType; }
+  TypeIndex getVBPtrType() const { return VBPtrType; }
+  uint64_t getVBPtrOffset() const { return VBPtrOffset; }
+  uint64_t getVTableIndex() const { return 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.
+  };
+  MemberAccess Access;
+  TypeIndex BaseType;
+  TypeIndex VBPtrType;
+  uint64_t VBPtrOffset;
+  uint64_t VTableIndex;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecords.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecords.def?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecords.def (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecords.def Wed May 11 12:47:35 2016
@@ -30,44 +30,44 @@
 #endif
 
 
-TYPE_RECORD(PointerType, LF_POINTER)
-TYPE_RECORD(TypeModifier, LF_MODIFIER)
-TYPE_RECORD(ProcedureType, LF_PROCEDURE)
-TYPE_RECORD(MemberFunctionType, LF_MFUNCTION)
-TYPE_RECORD(ArgList, LF_ARGLIST)
-
-TYPE_RECORD(ArrayType, LF_ARRAY)
-TYPE_RECORD(ClassType, LF_CLASS)
-TYPE_RECORD_ALIAS(ClassType, LF_STRUCTURE)
-TYPE_RECORD_ALIAS(ClassType, LF_INTERFACE)
-TYPE_RECORD(UnionType, LF_UNION)
-TYPE_RECORD(EnumType, LF_ENUM)
-TYPE_RECORD(TypeServer2, LF_TYPESERVER2)
-TYPE_RECORD(VFTableType, LF_VFTABLE)
-TYPE_RECORD(VTableShape, LF_VTSHAPE)
+TYPE_RECORD(PointerRecord, LF_POINTER)
+TYPE_RECORD(ModifierRecord, LF_MODIFIER)
+TYPE_RECORD(ProcedureRecord, LF_PROCEDURE)
+TYPE_RECORD(MemberFunctionRecord, LF_MFUNCTION)
+TYPE_RECORD(StringListRecord, LF_ARGLIST)
+
+TYPE_RECORD(ArrayRecord, LF_ARRAY)
+TYPE_RECORD(ClassRecord, LF_CLASS)
+TYPE_RECORD_ALIAS(ClassRecord, LF_STRUCTURE)
+TYPE_RECORD_ALIAS(ClassRecord, LF_INTERFACE)
+TYPE_RECORD(UnionRecord, LF_UNION)
+TYPE_RECORD(EnumRecord, LF_ENUM)
+TYPE_RECORD(TypeServer2Record, LF_TYPESERVER2)
+TYPE_RECORD(VirtualTableRecord, LF_VFTABLE)
+TYPE_RECORD(VirtualTableShapeRecord, LF_VTSHAPE)
 
 // Member type records. These are generally not length prefixed, and appear
 // inside of a field list record.
-MEMBER_RECORD(BaseClass, LF_BCLASS)
-MEMBER_RECORD_ALIAS(BaseClass, LF_BINTERFACE)
-MEMBER_RECORD(VirtualBaseClass, LF_VBCLASS)
-MEMBER_RECORD_ALIAS(VirtualBaseClass, LF_IVBCLASS)
-MEMBER_RECORD(VirtualFunctionPointer, LF_VFUNCTAB)
-MEMBER_RECORD(StaticDataMember, LF_STMEMBER)
-MEMBER_RECORD(OverloadedMethod, LF_METHOD)
-MEMBER_RECORD(DataMember, LF_MEMBER)
-MEMBER_RECORD(NestedType, LF_NESTTYPE)
-MEMBER_RECORD(OneMethod, LF_ONEMETHOD)
-MEMBER_RECORD(Enumerator, LF_ENUMERATE)
+MEMBER_RECORD(BaseClassRecord, LF_BCLASS)
+MEMBER_RECORD_ALIAS(BaseClassRecord, LF_BINTERFACE)
+MEMBER_RECORD(VirtualBaseClassRecord, LF_VBCLASS)
+MEMBER_RECORD_ALIAS(VirtualBaseClassRecord, LF_IVBCLASS)
+MEMBER_RECORD(VirtualFunctionPointerRecord, LF_VFUNCTAB)
+MEMBER_RECORD(StaticDataMemberRecord, LF_STMEMBER)
+MEMBER_RECORD(OverloadedMethodRecord, LF_METHOD)
+MEMBER_RECORD(DataMemberRecord, LF_MEMBER)
+MEMBER_RECORD(NestedTypeRecord, LF_NESTTYPE)
+MEMBER_RECORD(OneMethodRecord, LF_ONEMETHOD)
+MEMBER_RECORD(EnumeratorRecord, LF_ENUMERATE)
 
 // ID leaf records. Subsequent leaf types may be referenced from .debug$S.
 
-TYPE_RECORD(FuncId, LF_FUNC_ID)
-TYPE_RECORD(MemberFuncId, LF_MFUNC_ID)
-TYPE_RECORD(BuildInfo, LF_BUILDINFO)
-TYPE_RECORD_ALIAS(ArgList, LF_SUBSTR_LIST)
-TYPE_RECORD(StringId, LF_STRING_ID)
-TYPE_RECORD(UDTSrcLine, LF_UDT_SRC_LINE)
+TYPE_RECORD(FuncIdRecord, LF_FUNC_ID)
+TYPE_RECORD(MemberFunctionIdRecord, LF_MFUNC_ID)
+TYPE_RECORD(BuildInfoRecord, LF_BUILDINFO)
+TYPE_RECORD_ALIAS(StringListRecord, LF_SUBSTR_LIST)
+TYPE_RECORD(StringIdRecord, LF_STRING_ID)
+TYPE_RECORD(UdtSourceLineRecord, LF_UDT_SRC_LINE)
 
 #undef TYPE_RECORD
 #undef TYPE_RECORD_ALIAS

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeStream.h Wed May 11 12:47:35 2016
@@ -15,7 +15,6 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/RecordIterator.h"
-#include "llvm/Object/Error.h"
 #include "llvm/Support/Endian.h"
 #include <cstdint>
 #include <system_error>
@@ -26,43 +25,6 @@ class APSInt;
 
 namespace codeview {
 
-/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if
-/// there are not enough bytes remaining. Reinterprets the consumed bytes as a
-/// T object and points 'Res' at them.
-template <typename T>
-inline std::error_code consumeObject(StringRef &Data, const T *&Res) {
-  if (Data.size() < sizeof(*Res))
-    return object::object_error::parse_failed;
-  Res = reinterpret_cast<const T *>(Data.data());
-  Data = Data.drop_front(sizeof(*Res));
-  return std::error_code();
-}
-
-inline std::error_code consumeUInt32(StringRef &Data, uint32_t &Res) {
-  const support::ulittle32_t *IntPtr;
-  if (auto EC = consumeObject(Data, IntPtr))
-    return EC;
-  Res = *IntPtr;
-  return std::error_code();
-}
-
-/// Decodes a numeric "leaf" value. These are integer literals encountered in
-/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
-/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
-/// that indicates the bitwidth and sign of the numeric data.
-bool decodeNumericLeaf(ArrayRef<uint8_t> &Data, APSInt &Num);
-
-inline bool decodeNumericLeaf(StringRef &Data, APSInt &Num) {
-  ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(Data.data()),
-                          Data.size());
-  bool Success = decodeNumericLeaf(Bytes, Num);
-  Data = StringRef(reinterpret_cast<const char *>(Bytes.data()), Bytes.size());
-  return Success;
-}
-
-/// Decode a numeric leaf value that is known to be a uint32_t.
-bool decodeUIntLeaf(ArrayRef<uint8_t> &Data, uint64_t &Num);
-
 typedef RecordIterator<TypeLeafKind> TypeIterator;
 
 inline iterator_range<TypeIterator> makeTypeRange(ArrayRef<uint8_t> Data) {

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h Wed May 11 12:47:35 2016
@@ -40,12 +40,11 @@ public:
   TypeIndex writeModifier(const ModifierRecord &Record);
   TypeIndex writeProcedure(const ProcedureRecord &Record);
   TypeIndex writeMemberFunction(const MemberFunctionRecord &Record);
-  TypeIndex writeArgumentList(const ArgumentListRecord &Record);
+  TypeIndex writeArgumentList(const StringListRecord &Record);
   TypeIndex writeRecord(TypeRecordBuilder &builder);
   TypeIndex writePointer(const PointerRecord &Record);
-  TypeIndex writePointerToMember(const PointerToMemberRecord &Record);
   TypeIndex writeArray(const ArrayRecord &Record);
-  TypeIndex writeAggregate(const AggregateRecord &Record);
+  TypeIndex writeClass(const ClassRecord &Record);
   TypeIndex writeEnum(const EnumRecord &Record);
   TypeIndex writeBitField(const BitFieldRecord &Record);
   TypeIndex writeVirtualTableShape(const VirtualTableShapeRecord &Record);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Wed May 11 12:47:35 2016
@@ -263,7 +263,7 @@ void CodeViewDebug::emitTypeInformation(
   // type here.
   unsigned ArgListIndex = getNextTypeIndex();
   OS.AddComment("Type record length");
-  OS.EmitIntValue(2 + sizeof(ArgList), 2);
+  OS.EmitIntValue(StringListRecord::getLayoutSize(), 2);
   OS.AddComment("Leaf type: LF_ARGLIST");
   OS.EmitIntValue(LF_ARGLIST, 2);
   OS.AddComment("Number of arguments");
@@ -271,7 +271,7 @@ void CodeViewDebug::emitTypeInformation(
 
   unsigned VoidFnTyIdx = getNextTypeIndex();
   OS.AddComment("Type record length");
-  OS.EmitIntValue(2 + sizeof(ProcedureType), 2);
+  OS.EmitIntValue(ProcedureRecord::getLayoutSize(), 2);
   OS.AddComment("Leaf type: LF_PROCEDURE");
   OS.EmitIntValue(LF_PROCEDURE, 2);
   OS.AddComment("Return type index");

Modified: llvm/trunk/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/FieldListRecordBuilder.cpp Wed May 11 12:47:35 2016
@@ -56,7 +56,7 @@ void FieldListRecordBuilder::writeMethod
                                          TypeIndex MethodList, StringRef Name) {
   TypeRecordBuilder &Builder = getBuilder();
 
-  Builder.writeTypeRecordKind(TypeRecordKind::Method);
+  Builder.writeTypeRecordKind(TypeRecordKind::OverloadedMethod);
   Builder.writeUInt16(OverloadCount);
   Builder.writeTypeIndex(MethodList);
   Builder.writeNullTerminatedString(Name);

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Wed May 11 12:47:35 2016
@@ -201,12 +201,10 @@ public:
 
   /// CVTypeVisitor overrides.
 #define TYPE_RECORD(ClassName, LeafEnum)                                       \
-  void visit##ClassName(TypeLeafKind LeafType, const ClassName *Record,        \
-                        ArrayRef<uint8_t> LeafData);
+  void visit##ClassName(TypeLeafKind LeafType, ClassName &Record);
 #define TYPE_RECORD_ALIAS(ClassName, LeafEnum)
 #define MEMBER_RECORD(ClassName, LeafEnum)                                     \
-  void visit##ClassName(TypeLeafKind LeafType, const ClassName *Record,        \
-                        ArrayRef<uint8_t> &FieldData);
+  void visit##ClassName(TypeLeafKind LeafType, ClassName &Record);
 #define MEMBER_RECORD_ALIAS(ClassName, LeafEnum)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
@@ -219,6 +217,8 @@ public:
   void visitTypeEnd(TypeLeafKind Leaf, ArrayRef<uint8_t> LeafData);
 
   void printMemberAttributes(MemberAttributes Attrs);
+  void printMemberAttributes(MemberAccess Access, MethodKind Kind,
+                             MethodOptions Options);
 
 private:
   /// Forwards to the dumper, which holds the persistent state from visitation.
@@ -240,17 +240,6 @@ private:
 
 } // end anonymous namespace
 
-/// Reinterpret a byte array as an array of characters. Does not interpret as
-/// a C string, as StringRef has several helpers (split) that make that easy.
-static StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
-  return StringRef(reinterpret_cast<const char *>(LeafData.data()),
-                   LeafData.size());
-}
-
-static StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData) {
-  return getBytesAsCharacters(LeafData).split('\0').first;
-}
-
 static StringRef getLeafTypeName(TypeLeafKind LT) {
   switch (LT) {
 #define KNOWN_TYPE(LeafName, Value, ClassName) \
@@ -286,164 +275,128 @@ void CVTypeDumperImpl::visitTypeEnd(Type
   W.startLine() << "}\n";
 }
 
-void CVTypeDumperImpl::visitStringId(TypeLeafKind Leaf, const StringId *String,
-                                     ArrayRef<uint8_t> LeafData) {
-  W.printHex("Id", String->id.getIndex());
-  StringRef StringData = getBytesAsCString(LeafData);
-  W.printString("StringData", StringData);
+void CVTypeDumperImpl::visitStringIdRecord(TypeLeafKind Leaf,
+                                           StringIdRecord &String) {
+  printTypeIndex("Id", String.getId());
+  W.printString("StringData", String.getString());
   // Put this in CVUDTNames so it gets printed with LF_UDT_SRC_LINE.
-  Name = StringData;
+  Name = String.getString();
 }
-
-void CVTypeDumperImpl::visitArgList(TypeLeafKind Leaf, const ArgList *Args,
-                                    ArrayRef<uint8_t> LeafData) {
-  W.printNumber("NumArgs", Args->NumArgs);
+void CVTypeDumperImpl::visitStringListRecord(TypeLeafKind Leaf,
+                                             StringListRecord &Args) {
+  auto Indices = Args.getIndices();
+  uint32_t Size = Indices.size();
+  W.printNumber("NumArgs", Size);
   ListScope Arguments(W, "Arguments");
   SmallString<256> TypeName("(");
-  for (uint32_t ArgI = 0; ArgI != Args->NumArgs; ++ArgI) {
-    const TypeIndex *Type;
-    if (!consumeObject(LeafData, Type))
-      return;
-    printTypeIndex("ArgType", *Type);
-    StringRef ArgTypeName = getTypeName(*Type);
+  for (uint32_t I = 0; I < Size; ++I) {
+    printTypeIndex("ArgType", Indices[I]);
+    StringRef ArgTypeName = getTypeName(Indices[I]);
     TypeName.append(ArgTypeName);
-    if (ArgI + 1 != Args->NumArgs)
+    if (I + 1 != Size)
       TypeName.append(", ");
   }
   TypeName.push_back(')');
   Name = CVTD.saveName(TypeName);
 }
 
-void CVTypeDumperImpl::visitClassType(TypeLeafKind Leaf, const ClassType *Class,
-                                      ArrayRef<uint8_t> LeafData) {
-  W.printNumber("MemberCount", Class->MemberCount);
-  uint16_t Props = Class->Properties;
+void CVTypeDumperImpl::visitClassRecord(TypeLeafKind Leaf, ClassRecord &Class) {
+  uint16_t Props = static_cast<uint16_t>(Class.getOptions());
+  W.printNumber("MemberCount", Class.getMemberCount());
   W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
-  printTypeIndex("FieldList", Class->FieldList);
-  printTypeIndex("DerivedFrom", Class->DerivedFrom);
-  printTypeIndex("VShape", Class->VShape);
-  uint64_t SizeOf;
-  if (!decodeUIntLeaf(LeafData, SizeOf))
-    return parseError();
-  W.printNumber("SizeOf", SizeOf);
-  StringRef LeafChars = getBytesAsCharacters(LeafData);
-  StringRef LinkageName;
-  std::tie(Name, LinkageName) = LeafChars.split('\0');
-  W.printString("Name", Name);
-  if (Props & uint16_t(ClassOptions::HasUniqueName)) {
-    LinkageName = LinkageName.split('\0').first;
-    if (LinkageName.empty())
-      return parseError();
-    W.printString("LinkageName", LinkageName);
-  }
+  printTypeIndex("FieldList", Class.getFieldList());
+  printTypeIndex("DerivedFrom", Class.getDerivationList());
+  printTypeIndex("VShape", Class.getVTableShape());
+  W.printNumber("SizeOf", Class.getSize());
+  W.printString("Name", Class.getName());
+  if (Props & uint16_t(ClassOptions::HasUniqueName))
+    W.printString("LinkageName", Class.getUniqueName());
+  Name = Class.getName();
 }
 
-void CVTypeDumperImpl::visitUnionType(TypeLeafKind Leaf, const UnionType *Union,
-                                      ArrayRef<uint8_t> LeafData) {
-  W.printNumber("MemberCount", Union->MemberCount);
-  uint16_t Props = Union->Properties;
+void CVTypeDumperImpl::visitUnionRecord(TypeLeafKind Leaf, UnionRecord &Union) {
+  uint16_t Props = static_cast<uint16_t>(Union.getOptions());
+  W.printNumber("MemberCount", Union.getMemberCount());
   W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
-  printTypeIndex("FieldList", Union->FieldList);
-  uint64_t SizeOf;
-  if (!decodeUIntLeaf(LeafData, SizeOf))
-    return parseError();
-  W.printNumber("SizeOf", SizeOf);
-  StringRef LeafChars = getBytesAsCharacters(LeafData);
-  StringRef LinkageName;
-  std::tie(Name, LinkageName) = LeafChars.split('\0');
-  W.printString("Name", Name);
-  if (Props & uint16_t(ClassOptions::HasUniqueName)) {
-    LinkageName = LinkageName.split('\0').first;
-    if (LinkageName.empty())
-      return parseError();
-    W.printString("LinkageName", LinkageName);
-  }
+  printTypeIndex("FieldList", Union.getFieldList());
+  W.printNumber("SizeOf", Union.getSize());
+  W.printString("Name", Union.getName());
+  if (Props & uint16_t(ClassOptions::HasUniqueName))
+    W.printString("LinkageName", Union.getUniqueName());
+  Name = Union.getName();
 }
 
-void CVTypeDumperImpl::visitEnumType(TypeLeafKind Leaf, const EnumType *Enum,
-                                     ArrayRef<uint8_t> LeafData) {
-  W.printNumber("NumEnumerators", Enum->NumEnumerators);
-  W.printFlags("Properties", uint16_t(Enum->Properties),
+void CVTypeDumperImpl::visitEnumRecord(TypeLeafKind Leaf, EnumRecord &Enum) {
+  W.printNumber("NumEnumerators", Enum.getMemberCount());
+  W.printFlags("Properties", uint16_t(Enum.getOptions()),
                makeArrayRef(ClassOptionNames));
-  printTypeIndex("UnderlyingType", Enum->UnderlyingType);
-  printTypeIndex("FieldListType", Enum->FieldListType);
-  Name = getBytesAsCString(LeafData);
-  W.printString("Name", Name);
-}
-
-void CVTypeDumperImpl::visitArrayType(TypeLeafKind Leaf, const ArrayType *AT,
-                                      ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("ElementType", AT->ElementType);
-  printTypeIndex("IndexType", AT->IndexType);
-  uint64_t SizeOf;
-  if (!decodeUIntLeaf(LeafData, SizeOf))
-    return parseError();
-  W.printNumber("SizeOf", SizeOf);
-  Name = getBytesAsCString(LeafData);
-  W.printString("Name", Name);
-}
-
-void CVTypeDumperImpl::visitVFTableType(TypeLeafKind Leaf,
-                                        const VFTableType *VFT,
-                                        ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("CompleteClass", VFT->CompleteClass);
-  printTypeIndex("OverriddenVFTable", VFT->OverriddenVFTable);
-  W.printHex("VFPtrOffset", VFT->VFPtrOffset);
-  StringRef NamesData = getBytesAsCharacters(LeafData.slice(0, VFT->NamesLen));
-  std::tie(Name, NamesData) = NamesData.split('\0');
-  W.printString("VFTableName", Name);
-  while (!NamesData.empty()) {
-    StringRef MethodName;
-    std::tie(MethodName, NamesData) = NamesData.split('\0');
-    W.printString("MethodName", MethodName);
-  }
-}
-
-void CVTypeDumperImpl::visitMemberFuncId(TypeLeafKind Leaf,
-                                         const MemberFuncId *Id,
-                                         ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("ClassType", Id->ClassType);
-  printTypeIndex("FunctionType", Id->FunctionType);
-  Name = getBytesAsCString(LeafData);
-  W.printString("Name", Name);
-}
-
-void CVTypeDumperImpl::visitProcedureType(TypeLeafKind Leaf,
-                                          const ProcedureType *Proc,
-                                          ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("ReturnType", Proc->ReturnType);
-  W.printEnum("CallingConvention", uint8_t(Proc->CallConv),
+  printTypeIndex("UnderlyingType", Enum.getUnderlyingType());
+  printTypeIndex("FieldListType", Enum.getFieldList());
+  W.printString("Name", Enum.getName());
+  Name = Enum.getName();
+}
+
+void CVTypeDumperImpl::visitArrayRecord(TypeLeafKind Leaf, ArrayRecord &AT) {
+  printTypeIndex("ElementType", AT.getElementType());
+  printTypeIndex("IndexType", AT.getIndexType());
+  W.printNumber("SizeOf", AT.getSize());
+  W.printString("Name", AT.getName());
+  Name = AT.getName();
+}
+
+void CVTypeDumperImpl::visitVirtualTableRecord(TypeLeafKind Leaf,
+                                               VirtualTableRecord &VFT) {
+  printTypeIndex("CompleteClass", VFT.getCompleteClass());
+  printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
+  W.printHex("VFPtrOffset", VFT.getVFPtrOffset());
+  W.printString("VFTableName", VFT.getName());
+  for (auto N : VFT.getMethodNames())
+    W.printString("MethodName", N);
+  Name = VFT.getName();
+}
+
+void CVTypeDumperImpl::visitMemberFunctionIdRecord(TypeLeafKind Leaf,
+                                                   MemberFunctionIdRecord &Id) {
+  printTypeIndex("ClassType", Id.getClassType());
+  printTypeIndex("FunctionType", Id.getFunctionType());
+  W.printString("Name", Id.getName());
+  Name = Id.getName();
+}
+
+void CVTypeDumperImpl::visitProcedureRecord(TypeLeafKind Leaf,
+                                            ProcedureRecord &Proc) {
+  printTypeIndex("ReturnType", Proc.getReturnType());
+  W.printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
               makeArrayRef(CallingConventions));
-  W.printFlags("FunctionOptions", uint8_t(Proc->Options),
+  W.printFlags("FunctionOptions", uint8_t(Proc.getOptions()),
                makeArrayRef(FunctionOptionEnum));
-  W.printNumber("NumParameters", Proc->NumParameters);
-  printTypeIndex("ArgListType", Proc->ArgListType);
+  W.printNumber("NumParameters", Proc.getParameterCount());
+  printTypeIndex("ArgListType", Proc.getArgumentList());
 
-  StringRef ReturnTypeName = getTypeName(Proc->ReturnType);
-  StringRef ArgListTypeName = getTypeName(Proc->ArgListType);
+  StringRef ReturnTypeName = getTypeName(Proc.getReturnType());
+  StringRef ArgListTypeName = getTypeName(Proc.getArgumentList());
   SmallString<256> TypeName(ReturnTypeName);
   TypeName.push_back(' ');
   TypeName.append(ArgListTypeName);
   Name = CVTD.saveName(TypeName);
 }
 
-void CVTypeDumperImpl::visitMemberFunctionType(
-    TypeLeafKind Leaf, const MemberFunctionType *MemberFunc,
-    ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("ReturnType", MemberFunc->ReturnType);
-  printTypeIndex("ClassType", MemberFunc->ClassType);
-  printTypeIndex("ThisType", MemberFunc->ThisType);
-  W.printEnum("CallingConvention", uint8_t(MemberFunc->CallConv),
+void CVTypeDumperImpl::visitMemberFunctionRecord(TypeLeafKind Leaf,
+                                                 MemberFunctionRecord &MF) {
+  printTypeIndex("ReturnType", MF.getReturnType());
+  printTypeIndex("ClassType", MF.getClassType());
+  printTypeIndex("ThisType", MF.getThisType());
+  W.printEnum("CallingConvention", uint8_t(MF.getCallConv()),
               makeArrayRef(CallingConventions));
-  W.printFlags("FunctionOptions", uint8_t(MemberFunc->Options),
+  W.printFlags("FunctionOptions", uint8_t(MF.getOptions()),
                makeArrayRef(FunctionOptionEnum));
-  W.printNumber("NumParameters", MemberFunc->NumParameters);
-  printTypeIndex("ArgListType", MemberFunc->ArgListType);
-  W.printNumber("ThisAdjustment", MemberFunc->ThisAdjustment);
-
-  StringRef ReturnTypeName = getTypeName(MemberFunc->ReturnType);
-  StringRef ClassTypeName = getTypeName(MemberFunc->ClassType);
-  StringRef ArgListTypeName = getTypeName(MemberFunc->ArgListType);
+  W.printNumber("NumParameters", MF.getParameterCount());
+  printTypeIndex("ArgListType", MF.getArgumentList());
+  W.printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
+
+  StringRef ReturnTypeName = getTypeName(MF.getReturnType());
+  StringRef ClassTypeName = getTypeName(MF.getClassType());
+  StringRef ArgListTypeName = getTypeName(MF.getArgumentList());
   SmallString<256> TypeName(ReturnTypeName);
   TypeName.push_back(' ');
   TypeName.append(ClassTypeName);
@@ -455,148 +408,141 @@ void CVTypeDumperImpl::visitMemberFuncti
 void CVTypeDumperImpl::visitMethodList(TypeLeafKind Leaf,
                                        ArrayRef<uint8_t> LeafData) {
   while (!LeafData.empty()) {
-    const MethodListEntry *Method;
-    if (!consumeObject(LeafData, Method))
+    auto Method =
+        MethodListRecord::deserialize(TypeRecordKind::MethodList, LeafData);
+    if (Method)
       return;
+    const MethodListRecord &M = *Method;
+
     ListScope S(W, "Method");
-    printMemberAttributes(Method->Attrs);
-    printTypeIndex("Type", Method->Type);
-    if (Method->isIntroducedVirtual()) {
-      const little32_t *VFTOffsetPtr;
-      if (!consumeObject(LeafData, VFTOffsetPtr))
-        return;
-      W.printHex("VFTableOffset", *VFTOffsetPtr);
-    }
+    printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions());
+    printTypeIndex("Type", Method->getType());
+    if (Method->getMethodKind() == MethodKind::IntroducingVirtual ||
+        Method->getMethodKind() == MethodKind::PureIntroducingVirtual)
+      W.printHex("VFTableOffset", Method->getVFTableOffset());
   }
 }
 
-void CVTypeDumperImpl::visitFuncId(TypeLeafKind Leaf, const FuncId *Func,
-                                   ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("ParentScope", Func->ParentScope);
-  printTypeIndex("FunctionType", Func->FunctionType);
-  Name = getBytesAsCString(LeafData);
-  W.printString("Name", Name);
-}
-
-void CVTypeDumperImpl::visitTypeServer2(TypeLeafKind Leaf,
-                                        const TypeServer2 *TypeServer,
-                                        ArrayRef<uint8_t> LeafData) {
-  W.printBinary("Signature", StringRef(TypeServer->Signature, 16));
-  W.printNumber("Age", TypeServer->Age);
-  Name = getBytesAsCString(LeafData);
-  W.printString("Name", Name);
-}
-
-void CVTypeDumperImpl::visitPointerType(TypeLeafKind Leaf,
-                                        const PointerType *Ptr,
-                                        ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("PointeeType", Ptr->PointeeType);
-  W.printHex("PointerAttributes", Ptr->Attrs);
-  W.printEnum("PtrType", unsigned(Ptr->getPtrKind()),
+void CVTypeDumperImpl::visitFuncIdRecord(TypeLeafKind Leaf,
+                                         FuncIdRecord &Func) {
+  printTypeIndex("ParentScope", Func.getParentScope());
+  printTypeIndex("FunctionType", Func.getFunctionType());
+  W.printString("Name", Func.getName());
+  Name = Func.getName();
+}
+
+void CVTypeDumperImpl::visitTypeServer2Record(TypeLeafKind Leaf,
+                                              TypeServer2Record &TS) {
+  W.printBinary("Signature", TS.getGuid());
+  W.printNumber("Age", TS.getAge());
+  W.printString("Name", TS.getName());
+  Name = TS.getName();
+}
+
+void CVTypeDumperImpl::visitPointerRecord(TypeLeafKind Leaf,
+                                          PointerRecord &Ptr) {
+  printTypeIndex("PointeeType", Ptr.getReferentType());
+  W.printHex("PointerAttributes", uint32_t(Ptr.getOptions()));
+  W.printEnum("PtrType", unsigned(Ptr.getPointerKind()),
               makeArrayRef(PtrKindNames));
-  W.printEnum("PtrMode", unsigned(Ptr->getPtrMode()),
-              makeArrayRef(PtrModeNames));
-  W.printNumber("IsFlat", Ptr->isFlat());
-  W.printNumber("IsConst", Ptr->isConst());
-  W.printNumber("IsVolatile", Ptr->isVolatile());
-  W.printNumber("IsUnaligned", Ptr->isUnaligned());
-
-  if (Ptr->isPointerToMember()) {
-    const PointerToMemberTail *PMT;
-    if (!consumeObject(LeafData, PMT))
-      return;
-    printTypeIndex("ClassType", PMT->ClassType);
-    W.printEnum("Representation", PMT->Representation,
+  W.printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames));
+
+  W.printNumber("IsFlat", Ptr.isFlat());
+  W.printNumber("IsConst", Ptr.isConst());
+  W.printNumber("IsVolatile", Ptr.isVolatile());
+  W.printNumber("IsUnaligned", Ptr.isUnaligned());
+
+  if (Ptr.isPointerToMember()) {
+    const MemberPointerInfo &MI = Ptr.getMemberInfo();
+
+    printTypeIndex("ClassType", MI.getContainingType());
+    W.printEnum("Representation", uint16_t(MI.getRepresentation()),
                 makeArrayRef(PtrMemberRepNames));
 
-    StringRef PointeeName = getTypeName(Ptr->PointeeType);
-    StringRef ClassName = getTypeName(PMT->ClassType);
+    StringRef PointeeName = getTypeName(Ptr.getReferentType());
+    StringRef ClassName = getTypeName(MI.getContainingType());
     SmallString<256> TypeName(PointeeName);
     TypeName.push_back(' ');
     TypeName.append(ClassName);
     TypeName.append("::*");
     Name = CVTD.saveName(TypeName);
   } else {
-    W.printBinaryBlock("TailData", getBytesAsCharacters(LeafData));
-
     SmallString<256> TypeName;
-    if (Ptr->isConst())
+    if (Ptr.isConst())
       TypeName.append("const ");
-    if (Ptr->isVolatile())
+    if (Ptr.isVolatile())
       TypeName.append("volatile ");
-    if (Ptr->isUnaligned())
+    if (Ptr.isUnaligned())
       TypeName.append("__unaligned ");
 
-    TypeName.append(getTypeName(Ptr->PointeeType));
+    TypeName.append(getTypeName(Ptr.getReferentType()));
 
-    if (Ptr->getPtrMode() == PointerMode::LValueReference)
+    if (Ptr.getMode() == PointerMode::LValueReference)
       TypeName.append("&");
-    else if (Ptr->getPtrMode() == PointerMode::RValueReference)
+    else if (Ptr.getMode() == PointerMode::RValueReference)
       TypeName.append("&&");
-    else if (Ptr->getPtrMode() == PointerMode::Pointer)
+    else if (Ptr.getMode() == PointerMode::Pointer)
       TypeName.append("*");
 
     Name = CVTD.saveName(TypeName);
   }
 }
 
-void CVTypeDumperImpl::visitTypeModifier(TypeLeafKind Leaf,
-                                         const TypeModifier *Mod,
-                                         ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("ModifiedType", Mod->ModifiedType);
-  W.printFlags("Modifiers", Mod->Modifiers, makeArrayRef(TypeModifierNames));
+void CVTypeDumperImpl::visitModifierRecord(TypeLeafKind Leaf,
+                                           ModifierRecord &Mod) {
+  uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
+  printTypeIndex("ModifiedType", Mod.getModifiedType());
+  W.printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
 
-  StringRef ModifiedName = getTypeName(Mod->ModifiedType);
+  StringRef ModifiedName = getTypeName(Mod.getModifiedType());
   SmallString<256> TypeName;
-  if (Mod->Modifiers & uint16_t(ModifierOptions::Const))
+  if (Mods & uint16_t(ModifierOptions::Const))
     TypeName.append("const ");
-  if (Mod->Modifiers & uint16_t(ModifierOptions::Volatile))
+  if (Mods & uint16_t(ModifierOptions::Volatile))
     TypeName.append("volatile ");
-  if (Mod->Modifiers & uint16_t(ModifierOptions::Unaligned))
+  if (Mods & uint16_t(ModifierOptions::Unaligned))
     TypeName.append("__unaligned ");
   TypeName.append(ModifiedName);
   Name = CVTD.saveName(TypeName);
 }
 
-void CVTypeDumperImpl::visitVTableShape(TypeLeafKind Leaf,
-                                        const VTableShape *Shape,
-                                        ArrayRef<uint8_t> LeafData) {
-  unsigned VFEntryCount = Shape->VFEntryCount;
-  W.printNumber("VFEntryCount", VFEntryCount);
-  // We could print out whether the methods are near or far, but in practice
-  // today everything is CV_VTS_near32, so it's just noise.
+void CVTypeDumperImpl::visitVirtualTableShapeRecord(
+    TypeLeafKind Leaf, VirtualTableShapeRecord &Shape) {
+  W.printNumber("VFEntryCount", Shape.getEntryCount());
 }
 
-void CVTypeDumperImpl::visitUDTSrcLine(TypeLeafKind Leaf,
-                                       const UDTSrcLine *Line,
-                                       ArrayRef<uint8_t> LeafData) {
-  printTypeIndex("UDT", Line->UDT);
-  printTypeIndex("SourceFile", Line->SourceFile);
-  W.printNumber("LineNumber", Line->LineNumber);
+void CVTypeDumperImpl::visitUdtSourceLineRecord(TypeLeafKind Leaf,
+                                                UdtSourceLineRecord &Line) {
+  printTypeIndex("UDT", Line.getUDT());
+  printTypeIndex("SourceFile", Line.getSourceFile());
+  W.printNumber("LineNumber", Line.getLineNumber());
 }
 
-void CVTypeDumperImpl::visitBuildInfo(TypeLeafKind Leaf, const BuildInfo *Args,
-                                      ArrayRef<uint8_t> LeafData) {
-  W.printNumber("NumArgs", Args->NumArgs);
+void CVTypeDumperImpl::visitBuildInfoRecord(TypeLeafKind Leaf,
+                                            BuildInfoRecord &Args) {
+  W.printNumber("NumArgs", Args.getArgs().size());
 
   ListScope Arguments(W, "Arguments");
-  for (uint32_t ArgI = 0; ArgI != Args->NumArgs; ++ArgI) {
-    const TypeIndex *Type;
-    if (!consumeObject(LeafData, Type))
-      return;
-    printTypeIndex("ArgType", *Type);
+  for (auto Arg : Args.getArgs()) {
+    printTypeIndex("ArgType", Arg);
   }
 }
 
 void CVTypeDumperImpl::printMemberAttributes(MemberAttributes Attrs) {
-  W.printEnum("AccessSpecifier", uint8_t(Attrs.getAccess()),
+  return printMemberAttributes(Attrs.getAccess(), Attrs.getMethodKind(),
+                               Attrs.getFlags());
+}
+
+void CVTypeDumperImpl::printMemberAttributes(MemberAccess Access,
+                                             MethodKind Kind,
+                                             MethodOptions Options) {
+  W.printEnum("AccessSpecifier", uint8_t(Access),
               makeArrayRef(MemberAccessNames));
-  auto MK = Attrs.getMethodKind();
   // Data members will be vanilla. Don't try to print a method kind for them.
-  if (MK != MethodKind::Vanilla)
-    W.printEnum("MethodKind", unsigned(MK), makeArrayRef(MemberKindNames));
-  if (Attrs.getFlags() != MethodOptions::None) {
-    W.printFlags("MethodOptions", unsigned(Attrs.getFlags()),
+  if (Kind != MethodKind::Vanilla)
+    W.printEnum("MethodKind", unsigned(Kind), makeArrayRef(MemberKindNames));
+  if (Options != MethodOptions::None) {
+    W.printFlags("MethodOptions", unsigned(Options),
                  makeArrayRef(MethodOptionNames));
   }
 }
@@ -605,117 +551,91 @@ void CVTypeDumperImpl::visitUnknownMembe
   W.printHex("UnknownMember", unsigned(Leaf));
 }
 
-void CVTypeDumperImpl::visitNestedType(TypeLeafKind Leaf,
-                                       const NestedType *Nested,
-                                       ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitNestedTypeRecord(TypeLeafKind Leaf,
+                                             NestedTypeRecord &Nested) {
   DictScope S(W, "NestedType");
-  printTypeIndex("Type", Nested->Type);
-  StringRef Name = getBytesAsCString(FieldData);
-  FieldData = FieldData.drop_front(Name.size() + 1);
-  W.printString("Name", Name);
+  printTypeIndex("Type", Nested.getNestedType());
+  W.printString("Name", Nested.getName());
+  Name = Nested.getName();
 }
 
-void CVTypeDumperImpl::visitOneMethod(TypeLeafKind Leaf,
-                                      const OneMethod *Method,
-                                      ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitOneMethodRecord(TypeLeafKind Leaf,
+                                            OneMethodRecord &Method) {
   DictScope S(W, "OneMethod");
-  printMemberAttributes(Method->Attrs);
-  printTypeIndex("Type", Method->Type);
+  MethodKind K = Method.getKind();
+  printMemberAttributes(Method.getAccess(), K, Method.getOptions());
+  printTypeIndex("Type", Method.getType());
   // If virtual, then read the vftable offset.
-  if (Method->isIntroducedVirtual()) {
-    const little32_t *VFTOffsetPtr;
-    if (!consumeObject(FieldData, VFTOffsetPtr))
-      return;
-    W.printHex("VFTableOffset", *VFTOffsetPtr);
-  }
-  StringRef Name = getBytesAsCString(FieldData);
-  FieldData = FieldData.drop_front(Name.size() + 1);
-  W.printString("Name", Name);
+  if (Method.isIntroducingVirtual())
+    W.printHex("VFTableOffset", Method.getVFTableOffset());
+  W.printString("Name", Method.getName());
+  Name = Method.getName();
 }
 
-void CVTypeDumperImpl::visitOverloadedMethod(TypeLeafKind Leaf,
-                                             const OverloadedMethod *Method,
-                                             ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitOverloadedMethodRecord(
+    TypeLeafKind Leaf, OverloadedMethodRecord &Method) {
   DictScope S(W, "OverloadedMethod");
-  W.printHex("MethodCount", Method->MethodCount);
-  W.printHex("MethodListIndex", Method->MethList.getIndex());
-  StringRef Name = getBytesAsCString(FieldData);
-  FieldData = FieldData.drop_front(Name.size() + 1);
-  W.printString("Name", Name);
+  W.printHex("MethodCount", Method.getNumOverloads());
+  printTypeIndex("MethodListIndex", Method.getMethodList());
+  W.printString("Name", Method.getName());
+  Name = Method.getName();
 }
 
-void CVTypeDumperImpl::visitDataMember(TypeLeafKind Leaf,
-                                       const DataMember *Field,
-                                       ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitDataMemberRecord(TypeLeafKind Leaf,
+                                             DataMemberRecord &Field) {
   DictScope S(W, "DataMember");
-  printMemberAttributes(Field->Attrs);
-  printTypeIndex("Type", Field->Type);
-  uint64_t FieldOffset;
-  if (!decodeUIntLeaf(FieldData, FieldOffset))
-    return parseError();
-  W.printHex("FieldOffset", FieldOffset);
-  StringRef Name = getBytesAsCString(FieldData);
-  FieldData = FieldData.drop_front(Name.size() + 1);
-  W.printString("Name", Name);
+  printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
+                        MethodOptions::None);
+  printTypeIndex("Type", Field.getType());
+  W.printHex("FieldOffset", Field.getFieldOffset());
+  W.printString("Name", Field.getName());
+  Name = Field.getName();
 }
 
-void CVTypeDumperImpl::visitStaticDataMember(TypeLeafKind Leaf,
-                                             const StaticDataMember *Field,
-                                             ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitStaticDataMemberRecord(
+    TypeLeafKind Leaf, StaticDataMemberRecord &Field) {
   DictScope S(W, "StaticDataMember");
-  printMemberAttributes(Field->Attrs);
-  printTypeIndex("Type", Field->Type);
-  StringRef Name = getBytesAsCString(FieldData);
-  FieldData = FieldData.drop_front(Name.size() + 1);
-  W.printString("Name", Name);
+  printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
+                        MethodOptions::None);
+  printTypeIndex("Type", Field.getType());
+  W.printString("Name", Field.getName());
+  Name = Field.getName();
 }
 
-void CVTypeDumperImpl::visitVirtualFunctionPointer(
-    TypeLeafKind Leaf, const VirtualFunctionPointer *VFTable,
-    ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitVirtualFunctionPointerRecord(
+    TypeLeafKind Leaf, VirtualFunctionPointerRecord &VFTable) {
   DictScope S(W, "VirtualFunctionPointer");
-  printTypeIndex("Type", VFTable->Type);
+  printTypeIndex("Type", VFTable.getType());
 }
 
-void CVTypeDumperImpl::visitEnumerator(TypeLeafKind Leaf,
-                                       const Enumerator *Enum,
-                                       ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitEnumeratorRecord(TypeLeafKind Leaf,
+                                             EnumeratorRecord &Enum) {
   DictScope S(W, "Enumerator");
-  printMemberAttributes(Enum->Attrs);
-  APSInt EnumValue;
-  if (!decodeNumericLeaf(FieldData, EnumValue))
-    return parseError();
-  W.printNumber("EnumValue", EnumValue);
-  StringRef Name = getBytesAsCString(FieldData);
-  FieldData = FieldData.drop_front(Name.size() + 1);
-  W.printString("Name", Name);
+  printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
+                        MethodOptions::None);
+  W.printNumber("EnumValue", Enum.getValue());
+  W.printString("Name", Enum.getName());
+  Name = Enum.getName();
 }
 
-void CVTypeDumperImpl::visitBaseClass(TypeLeafKind Leaf, const BaseClass *Base,
-                                      ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitBaseClassRecord(TypeLeafKind Leaf,
+                                            BaseClassRecord &Base) {
   DictScope S(W, "BaseClass");
-  printMemberAttributes(Base->Attrs);
-  printTypeIndex("BaseType", Base->BaseType);
-  uint64_t BaseOffset;
-  if (!decodeUIntLeaf(FieldData, BaseOffset))
-    return parseError();
-  W.printHex("BaseOffset", BaseOffset);
+  printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
+                        MethodOptions::None);
+  printTypeIndex("BaseType", Base.getBaseType());
+  W.printHex("BaseOffset", Base.getBaseOffset());
 }
 
-void CVTypeDumperImpl::visitVirtualBaseClass(TypeLeafKind Leaf,
-                                             const VirtualBaseClass *Base,
-                                             ArrayRef<uint8_t> &FieldData) {
+void CVTypeDumperImpl::visitVirtualBaseClassRecord(
+    TypeLeafKind Leaf, VirtualBaseClassRecord &Base) {
   DictScope S(W, "VirtualBaseClass");
-  printMemberAttributes(Base->Attrs);
-  printTypeIndex("BaseType", Base->BaseType);
-  printTypeIndex("VBPtrType", Base->VBPtrType);
-  uint64_t VBPtrOffset, VBTableIndex;
-  if (!decodeUIntLeaf(FieldData, VBPtrOffset))
-    return parseError();
-  if (!decodeUIntLeaf(FieldData, VBTableIndex))
-    return parseError();
-  W.printHex("VBPtrOffset", VBPtrOffset);
-  W.printHex("VBTableIndex", VBTableIndex);
+  printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
+                        MethodOptions::None);
+  printTypeIndex("BaseType", Base.getBaseType());
+  printTypeIndex("VBPtrType", Base.getVBPtrType());
+  W.printHex("VBPtrOffset", Base.getVBPtrOffset());
+  W.printHex("VBTableIndex", Base.getVTableIndex());
 }
 
 StringRef CVTypeDumper::getTypeName(TypeIndex TI) {

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStream.cpp?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeStream.cpp Wed May 11 12:47:35 2016
@@ -13,7 +13,7 @@
 
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/APSInt.h"
-#include "llvm/DebugInfo/CodeView/TypeStream.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
 
 using namespace llvm;
 using namespace llvm::codeview;

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp?rev=269216&r1=269215&r2=269216&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeTableBuilder.cpp Wed May 11 12:47:35 2016
@@ -17,27 +17,6 @@
 using namespace llvm;
 using namespace codeview;
 
-namespace {
-
-const int PointerKindShift = 0;
-const int PointerModeShift = 5;
-const int PointerSizeShift = 13;
-
-const int ClassHfaKindShift = 11;
-const int ClassWindowsRTClassKindShift = 14;
-
-void writePointerBase(TypeRecordBuilder &Builder,
-                      const PointerRecordBase &Record) {
-  Builder.writeTypeIndex(Record.getReferentType());
-  uint32_t flags =
-      static_cast<uint32_t>(Record.getOptions()) |
-      (Record.getSize() << PointerSizeShift) |
-      (static_cast<uint32_t>(Record.getMode()) << PointerModeShift) |
-      (static_cast<uint32_t>(Record.getPointerKind()) << PointerKindShift);
-  Builder.writeUInt32(flags);
-}
-}
-
 TypeTableBuilder::TypeTableBuilder() {}
 
 TypeTableBuilder::~TypeTableBuilder() {}
@@ -46,7 +25,7 @@ TypeIndex TypeTableBuilder::writeModifie
   TypeRecordBuilder Builder(TypeRecordKind::Modifier);
 
   Builder.writeTypeIndex(Record.getModifiedType());
-  Builder.writeUInt16(static_cast<uint16_t>(Record.getOptions()));
+  Builder.writeUInt16(static_cast<uint16_t>(Record.getModifiers()));
 
   return writeRecord(Builder);
 }
@@ -79,12 +58,11 @@ TypeTableBuilder::writeMemberFunction(co
   return writeRecord(Builder);
 }
 
-TypeIndex
-TypeTableBuilder::writeArgumentList(const ArgumentListRecord &Record) {
+TypeIndex TypeTableBuilder::writeArgumentList(const StringListRecord &Record) {
   TypeRecordBuilder Builder(TypeRecordKind::ArgumentList);
 
-  Builder.writeUInt32(Record.getArgumentTypes().size());
-  for (TypeIndex TI : Record.getArgumentTypes()) {
+  Builder.writeUInt32(Record.getIndices().size());
+  for (TypeIndex TI : Record.getIndices()) {
     Builder.writeTypeIndex(TI);
   }
 
@@ -94,19 +72,20 @@ TypeTableBuilder::writeArgumentList(cons
 TypeIndex TypeTableBuilder::writePointer(const PointerRecord &Record) {
   TypeRecordBuilder Builder(TypeRecordKind::Pointer);
 
-  writePointerBase(Builder, Record);
-
-  return writeRecord(Builder);
-}
-
-TypeIndex
-TypeTableBuilder::writePointerToMember(const PointerToMemberRecord &Record) {
-  TypeRecordBuilder Builder(TypeRecordKind::Pointer);
-
-  writePointerBase(Builder, Record);
+  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.writeTypeIndex(Record.getContainingType());
-  Builder.writeUInt16(static_cast<uint16_t>(Record.getRepresentation()));
+  if (Record.isPointerToMember()) {
+    const MemberPointerInfo &M = Record.getMemberInfo();
+    Builder.writeTypeIndex(M.getContainingType());
+    Builder.writeUInt16(static_cast<uint16_t>(M.getRepresentation()));
+  }
 
   return writeRecord(Builder);
 }
@@ -122,7 +101,7 @@ TypeIndex TypeTableBuilder::writeArray(c
   return writeRecord(Builder);
 }
 
-TypeIndex TypeTableBuilder::writeAggregate(const AggregateRecord &Record) {
+TypeIndex TypeTableBuilder::writeClass(const ClassRecord &Record) {
   assert((Record.getKind() == TypeRecordKind::Structure) ||
          (Record.getKind() == TypeRecordKind::Class) ||
          (Record.getKind() == TypeRecordKind::Union));
@@ -132,18 +111,13 @@ TypeIndex TypeTableBuilder::writeAggrega
   Builder.writeUInt16(Record.getMemberCount());
   uint16_t Flags =
       static_cast<uint16_t>(Record.getOptions()) |
-      (static_cast<uint16_t>(Record.getHfa()) << ClassHfaKindShift) |
+      (static_cast<uint16_t>(Record.getHfa()) << ClassRecord::HfaKindShift) |
       (static_cast<uint16_t>(Record.getWinRTKind())
-       << ClassWindowsRTClassKindShift);
+       << ClassRecord::WinRTKindShift);
   Builder.writeUInt16(Flags);
   Builder.writeTypeIndex(Record.getFieldList());
-  if (Record.getKind() != TypeRecordKind::Union) {
-    Builder.writeTypeIndex(Record.getDerivationList());
-    Builder.writeTypeIndex(Record.getVTableShape());
-  } else {
-    assert(Record.getDerivationList() == TypeIndex());
-    assert(Record.getVTableShape() == TypeIndex());
-  }
+  Builder.writeTypeIndex(Record.getDerivationList());
+  Builder.writeTypeIndex(Record.getVTableShape());
   Builder.writeEncodedUnsignedInteger(Record.getSize());
   Builder.writeNullTerminatedString(Record.getName());
   if ((Record.getOptions() & ClassOptions::HasUniqueName) !=




More information about the llvm-commits mailing list