[llvm] r281556 - [pdb] Get rid of Data and RawData in CVType.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 14 16:00:16 PDT 2016


Author: zturner
Date: Wed Sep 14 18:00:16 2016
New Revision: 281556

URL: http://llvm.org/viewvc/llvm-project?rev=281556&view=rev
Log:
[pdb] Get rid of Data and RawData in CVType.

The `CVType` had two redundant fields which were confusing and
error-prone to fill out.  By treating member records as a distinct
type from leaf records, we are able to simplify this quite a bit.

Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D24432

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h
    llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
    llvm/trunk/lib/DebugInfo/PDB/Raw/TpiHashing.cpp
    llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp
    llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.h

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Wed Sep 14 18:00:16 2016
@@ -22,14 +22,27 @@
 namespace llvm {
 namespace codeview {
 
-template <typename Kind> struct CVRecord {
-  uint32_t Length;
+template <typename Kind> class CVRecord {
+public:
+  CVRecord() {}
+  CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
+
+  uint32_t length() const { return RecordData.size(); }
+  Kind kind() const { return Type; }
+  ArrayRef<uint8_t> data() const { return RecordData; }
+  ArrayRef<uint8_t> content() const {
+    return RecordData.drop_front(sizeof(RecordPrefix));
+  }
+  Optional<uint32_t> hash() const { return Hash; }
+
+  void setHash(uint32_t Value) { Hash = Value; }
+
   Kind Type;
-  ArrayRef<uint8_t> Data;
-  ArrayRef<uint8_t> RawData;
+  ArrayRef<uint8_t> RecordData;
   Optional<uint32_t> Hash;
 };
 }
+
 namespace msf {
 
 template <typename Kind>
@@ -43,17 +56,17 @@ struct VarStreamArrayExtractor<codeview:
 
     if (auto EC = Reader.readObject(Prefix))
       return EC;
-    Item.Length = Prefix->RecordLen;
-    if (Item.Length < 2)
+    if (Prefix->RecordLen < 2)
       return make_error<CodeViewError>(cv_error_code::corrupt_record);
-    Item.Type = static_cast<Kind>(uint16_t(Prefix->RecordKind));
+    Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
 
     Reader.setOffset(Offset);
+    ArrayRef<uint8_t> RawData;
     if (auto EC =
-            Reader.readBytes(Item.RawData, Item.Length + sizeof(uint16_t)))
+            Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
       return EC;
-    Item.Data = Item.RawData.slice(sizeof(RecordPrefix));
-    Len = Prefix->RecordLen + 2;
+    Item = codeview::CVRecord<Kind>(K, RawData);
+    Len = Item.length();
     return Error::success();
   }
 };

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h Wed Sep 14 18:00:16 2016
@@ -47,7 +47,7 @@ public:
 #include "CVSymbolTypes.def"
 
   void visitSymbolRecord(const CVRecord<SymbolKind> &Record) {
-    ArrayRef<uint8_t> Data = Record.Data;
+    ArrayRef<uint8_t> Data = Record.content();
     auto *DerivedThis = static_cast<Derived *>(this);
     DerivedThis->visitSymbolBegin(Record.Type, Data);
     uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Data) : 0;
@@ -70,7 +70,7 @@ public:
   SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
 #include "CVSymbolTypes.def"
     }
-    DerivedThis->visitSymbolEnd(Record.Type, Record.Data);
+    DerivedThis->visitSymbolEnd(Record.Type, Record.content());
   }
 
   /// Visits the symbol records in Data. Sets the error flag on parse failures.

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=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Wed Sep 14 18:00:16 2016
@@ -23,7 +23,8 @@ class CVTypeVisitor {
 public:
   explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
 
-  Error visitTypeRecord(CVRecord<TypeLeafKind> &Record);
+  Error visitTypeRecord(CVType &Record);
+  Error visitMemberRecord(CVMemberRecord &Record);
 
   /// Visits the type records in Data. Sets the error flag on parse failures.
   Error visitTypeStream(const CVTypeArray &Types);

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDeserializer.h Wed Sep 14 18:00:16 2016
@@ -20,12 +20,13 @@ public:
   TypeDeserializer() {}
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
-      override {                                                               \
+  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override {         \
     return defaultVisitKnownRecord(CVR, Record);                               \
   }
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
+    return defaultVisitKnownMember(CVR, Record);                               \
+  }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "TypeRecords.def"
@@ -44,13 +45,19 @@ protected:
   }
 
 private:
-  template <typename T>
-  Error defaultVisitKnownRecord(CVRecord<TypeLeafKind> &CVR, T &Record) {
-    ArrayRef<uint8_t> RD = CVR.Data;
+  template <typename T> Error defaultVisitKnownRecord(CVType &CVR, T &Record) {
+    ArrayRef<uint8_t> RD = CVR.content();
     if (auto EC = deserializeRecord(RD, CVR.Type, Record))
       return EC;
     return Error::success();
   }
+  template <typename T>
+  Error defaultVisitKnownMember(CVMemberRecord &CVMR, T &Record) {
+    ArrayRef<uint8_t> RD = CVMR.Data;
+    if (auto EC = deserializeRecord(RD, CVMR.Kind, Record))
+      return EC;
+    return Error::success();
+  }
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumper.h Wed Sep 14 18:00:16 2016
@@ -63,19 +63,20 @@ public:
   ScopedPrinter *getPrinter() { return W; }
 
   /// Action to take on unknown types. By default, they are ignored.
-  Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override;
-  Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) override;
+  Error visitUnknownType(CVType &Record) override;
+  Error visitUnknownMember(CVMemberRecord &Record) override;
 
   /// Paired begin/end actions for all types. Receives all record data,
   /// including the fixed-length record prefix.
-  Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
-  Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override;
+  Error visitTypeBegin(CVType &Record) override;
+  Error visitTypeEnd(CVType &Record) override;
+  Error visitMemberBegin(CVMemberRecord &Record) override;
+  Error visitMemberEnd(CVMemberRecord &Record) override;
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
-      override;
+  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "TypeRecords.def"

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=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeRecord.h Wed Sep 14 18:00:16 2016
@@ -29,6 +29,11 @@ using llvm::support::ulittle16_t;
 using llvm::support::ulittle32_t;
 
 typedef CVRecord<TypeLeafKind> CVType;
+
+struct CVMemberRecord {
+  TypeLeafKind Kind;
+  ArrayRef<uint8_t> Data;
+};
 typedef msf::VarStreamArray<CVType> CVTypeArray;
 
 /// Equvalent to CV_fldattr_t in cvinfo.h.

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h Wed Sep 14 18:00:16 2016
@@ -51,7 +51,8 @@ public:
   }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  virtual Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
+  virtual Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record)    \
+      override {                                                               \
     visitMemberRecordImpl(Record);                                             \
     return Error::success();                                                   \
   }
@@ -61,10 +62,7 @@ public:
 private:
   void updateCVRecord(CVType &Record) {
     StringRef S = TypeTableBuilder.getRecords().back();
-    ArrayRef<uint8_t> Data(S.bytes_begin(), S.bytes_end());
-    Record.RawData = Data;
-    Record.Data = Record.RawData.drop_front(sizeof(RecordPrefix));
-    Record.Length = Data.size() - sizeof(ulittle16_t);
+    Record.RecordData = ArrayRef<uint8_t>(S.bytes_begin(), S.bytes_end());
   }
   template <typename RecordKind>
   void visitKnownRecordImpl(CVType &CVR, RecordKind &Record) {

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h Wed Sep 14 18:00:16 2016
@@ -30,7 +30,7 @@ public:
     return Error::success();
   }
 
-  virtual Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitUnknownMember(CVMemberRecord &Record) override {
     for (auto Visitor : Pipeline) {
       if (auto EC = Visitor->visitUnknownMember(Record))
         return EC;
@@ -38,14 +38,14 @@ public:
     return Error::success();
   }
 
-  virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitTypeBegin(CVType &Record) override {
     for (auto Visitor : Pipeline) {
       if (auto EC = Visitor->visitTypeBegin(Record))
         return EC;
     }
     return Error::success();
   }
-  virtual Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitTypeEnd(CVType &Record) override {
     for (auto Visitor : Pipeline) {
       if (auto EC = Visitor->visitTypeEnd(Record))
         return EC;
@@ -53,13 +53,27 @@ public:
     return Error::success();
   }
 
+  virtual Error visitMemberBegin(CVMemberRecord &Record) override {
+    for (auto Visitor : Pipeline) {
+      if (auto EC = Visitor->visitMemberBegin(Record))
+        return EC;
+    }
+    return Error::success();
+  }
+  virtual Error visitMemberEnd(CVMemberRecord &Record) override {
+    for (auto Visitor : Pipeline) {
+      if (auto EC = Visitor->visitMemberEnd(Record))
+        return EC;
+    }
+    return Error::success();
+  }
+
   void addCallbackToPipeline(TypeVisitorCallbacks &Callbacks) {
     Pipeline.push_back(&Callbacks);
   }
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
-      override {                                                               \
+  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override {         \
     for (auto Visitor : Pipeline) {                                            \
       if (auto EC = Visitor->visitKnownRecord(CVR, Record))                    \
         return EC;                                                             \
@@ -67,7 +81,14 @@ public:
     return Error::success();                                                   \
   }
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  Error visitKnownMember(CVMemberRecord &CVMR, Name##Record &Record)           \
+      override {                                                               \
+    for (auto Visitor : Pipeline) {                                            \
+      if (auto EC = Visitor->visitKnownMember(CVMR, Record))                   \
+        return EC;                                                             \
+    }                                                                          \
+    return Error::success();                                                   \
+  }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h Wed Sep 14 18:00:16 2016
@@ -25,30 +25,32 @@ public:
   virtual ~TypeVisitorCallbacks() {}
 
   /// Action to take on unknown types. By default, they are ignored.
-  virtual Error visitUnknownType(CVRecord<TypeLeafKind> &Record) {
-    return Error::success();
-  }
-  virtual Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) {
-    return Error::success();
-  }
-
+  virtual Error visitUnknownType(CVType &Record) { return Error::success(); }
   /// Paired begin/end actions for all types. Receives all record data,
   /// including the fixed-length record prefix.  visitTypeBegin() should return
   /// the type of the Record, or an error if it cannot be determined.
-  virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
+  virtual Error visitTypeBegin(CVType &Record) { return Error::success(); }
+  virtual Error visitTypeEnd(CVType &Record) { return Error::success(); }
+
+  virtual Error visitUnknownMember(CVMemberRecord &Record) {
     return Error::success();
   }
-  virtual Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) {
+  virtual Error visitMemberBegin(CVMemberRecord &Record) {
+    return Error::success();
+  }
+  virtual Error visitMemberEnd(CVMemberRecord &Record) {
     return Error::success();
   }
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,                  \
-                                 Name##Record &Record) {                       \
+  virtual Error visitKnownRecord(CVType &CVR, Name##Record &Record) {          \
     return Error::success();                                                   \
   }
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  virtual Error visitKnownMember(CVMemberRecord &CVM, Name##Record &Record) {  \
+    return Error::success();                                                   \
+  }
+
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "TypeRecords.def"

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h Wed Sep 14 18:00:16 2016
@@ -32,11 +32,9 @@ class ReadableStreamRef;
 class WritableStream;
 
 template <> struct SequencedItemTraits<llvm::codeview::CVType> {
-  static size_t length(const codeview::CVType &Item) {
-    return Item.RawData.size();
-  }
+  static size_t length(const codeview::CVType &Item) { return Item.length(); }
   static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) {
-    return Item.RawData;
+    return Item.data();
   }
 };
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp Wed Sep 14 18:00:16 2016
@@ -42,8 +42,8 @@ static Error skipPadding(ArrayRef<uint8_
 }
 
 template <typename T>
-static Expected<CVType> deserializeMemberRecord(ArrayRef<uint8_t> &Data,
-                                                TypeLeafKind Kind) {
+static Expected<CVMemberRecord> deserializeMemberRecord(ArrayRef<uint8_t> &Data,
+                                                        TypeLeafKind Kind) {
   ArrayRef<uint8_t> OldData = Data;
   TypeRecordKind RK = static_cast<TypeRecordKind>(Kind);
   auto ExpectedRecord = T::deserialize(RK, Data);
@@ -53,20 +53,17 @@ static Expected<CVType> deserializeMembe
   if (auto EC = skipPadding(Data))
     return std::move(EC);
 
-  CVType CVR;
-  CVR.Type = Kind;
-  CVR.Length = OldData.size() - Data.size();
-  CVR.Data = OldData.slice(0, CVR.Length);
-  CVR.RawData = CVR.Data;
-  return CVR;
+  CVMemberRecord CVMR;
+  CVMR.Kind = Kind;
+  CVMR.Data = OldData.drop_back(Data.size());
+  return CVMR;
 }
 
 CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
     : Callbacks(Callbacks) {}
 
 template <typename T>
-static Error visitKnownRecord(CVRecord<TypeLeafKind> &Record,
-                              TypeVisitorCallbacks &Callbacks) {
+static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
   TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type);
   T KnownRecord(RK);
   if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
@@ -74,7 +71,17 @@ static Error visitKnownRecord(CVRecord<T
   return Error::success();
 }
 
-Error CVTypeVisitor::visitTypeRecord(CVRecord<TypeLeafKind> &Record) {
+template <typename T>
+static Error visitKnownMember(CVMemberRecord &Record,
+                              TypeVisitorCallbacks &Callbacks) {
+  TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Kind);
+  T KnownRecord(RK);
+  if (auto EC = Callbacks.visitKnownMember(Record, KnownRecord))
+    return EC;
+  return Error::success();
+}
+
+Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
   if (auto EC = Callbacks.visitTypeBegin(Record))
     return EC;
 
@@ -91,14 +98,40 @@ Error CVTypeVisitor::visitTypeRecord(CVR
   }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                  \
   TYPE_RECORD(EnumVal, EnumVal, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/TypeRecords.def"
+  }
+
+  if (auto EC = Callbacks.visitTypeEnd(Record))
+    return EC;
+
+  return Error::success();
+}
+
+Error CVTypeVisitor::visitMemberRecord(CVMemberRecord &Record) {
+  if (auto EC = Callbacks.visitMemberBegin(Record))
+    return EC;
+
+  switch (Record.Kind) {
+  default:
+    if (auto EC = Callbacks.visitUnknownMember(Record))
+      return EC;
+    break;
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  case EnumName: {                                                             \
+    if (auto EC = visitKnownMember<Name##Record>(Record, Callbacks))           \
+      return EC;                                                               \
+    break;                                                                     \
+  }
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                \
-  MEMBER_RECORD(EnumName, EnumVal, AliasName)
+  MEMBER_RECORD(EnumVal, EnumVal, AliasName)
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
   }
 
-  if (auto EC = Callbacks.visitTypeEnd(Record))
+  if (auto EC = Callbacks.visitMemberEnd(Record))
     return EC;
 
   return Error::success();
@@ -119,12 +152,12 @@ static Error visitKnownMember(ArrayRef<u
   auto ExpectedRecord = deserializeMemberRecord<MR>(Data, Leaf);
   if (!ExpectedRecord)
     return ExpectedRecord.takeError();
-  CVType &Record = *ExpectedRecord;
-  if (auto EC = Callbacks.visitTypeBegin(Record))
+  CVMemberRecord &Record = *ExpectedRecord;
+  if (auto EC = Callbacks.visitMemberBegin(Record))
     return EC;
-  if (auto EC = visitKnownRecord<MR>(Record, Callbacks))
+  if (auto EC = visitKnownMember<MR>(Record, Callbacks))
     return EC;
-  if (auto EC = Callbacks.visitTypeEnd(Record))
+  if (auto EC = Callbacks.visitMemberEnd(Record))
     return EC;
   return Error::success();
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumper.cpp Wed Sep 14 18:00:16 2016
@@ -204,15 +204,12 @@ static StringRef getLeafTypeName(TypeLea
 }
 
 Error CVTypeDumper::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
+  assert(!IsInFieldList);
   // Reset Name to the empty string. If the visitor sets it, we know it.
   Name = "";
 
   W->startLine() << getLeafTypeName(Record.Type);
-  if (!IsInFieldList) {
-    // If this is a field list member, don't record its type index because it
-    // doesn't have one.  Only the outer field list has a type index.
-    W->getOStream() << " (" << HexNumber(getNextTypeIndex()) << ")";
-  }
+  W->getOStream() << " (" << HexNumber(getNextTypeIndex()) << ")";
   W->getOStream() << " {\n";
   W->indent();
   W->printEnum("TypeLeafKind", unsigned(Record.Type),
@@ -220,7 +217,6 @@ Error CVTypeDumper::visitTypeBegin(CVRec
   if (Record.Type == LF_FIELDLIST) {
     // Record that we're in a field list so that members do not get assigned
     // type indices.
-    assert(!IsInFieldList);
     IsInFieldList = true;
   }
   return Error::success();
@@ -231,15 +227,37 @@ Error CVTypeDumper::visitTypeEnd(CVRecor
     assert(IsInFieldList);
     IsInFieldList = false;
   }
+  assert(!IsInFieldList);
 
-  if (!IsInFieldList) {
-    // Record every type that is not a field list member, even if Name is empty.
-    // CVUDTNames is indexed by type index, and must have one entry for every
-    // type.  Field list members are not recorded, and are only referenced by
-    // their containing field list record.
-    recordType(Name);
-  }
+  // Record every type that is not a field list member, even if Name is empty.
+  // CVUDTNames is indexed by type index, and must have one entry for every
+  // type.  Field list members are not recorded, and are only referenced by
+  // their containing field list record.
+  recordType(Name);
+
+  if (PrintRecordBytes)
+    W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));
+
+  W->unindent();
+  W->startLine() << "}\n";
+  return Error::success();
+}
+
+Error CVTypeDumper::visitMemberBegin(CVMemberRecord &Record) {
+  assert(IsInFieldList);
+  // Reset Name to the empty string. If the visitor sets it, we know it.
+  Name = "";
+
+  W->startLine() << getLeafTypeName(Record.Kind);
+  W->getOStream() << " {\n";
+  W->indent();
+  W->printEnum("TypeLeafKind", unsigned(Record.Kind),
+               makeArrayRef(LeafTypeNames));
+  return Error::success();
+}
 
+Error CVTypeDumper::visitMemberEnd(CVMemberRecord &Record) {
+  assert(IsInFieldList);
   if (PrintRecordBytes)
     W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
 
@@ -573,18 +591,18 @@ void CVTypeDumper::printMemberAttributes
   }
 }
 
-Error CVTypeDumper::visitUnknownMember(CVRecord<TypeLeafKind> &Record) {
-  W->printHex("UnknownMember", unsigned(Record.Type));
+Error CVTypeDumper::visitUnknownMember(CVMemberRecord &Record) {
+  W->printHex("UnknownMember", unsigned(Record.Kind));
   return Error::success();
 }
 
 Error CVTypeDumper::visitUnknownType(CVRecord<TypeLeafKind> &Record) {
-  W->printEnum("Kind", uint16_t(Record.Type), makeArrayRef(LeafTypeNames));
-  W->printNumber("Length", uint32_t(Record.Data.size()));
+  W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames));
+  W->printNumber("Length", uint32_t(Record.content().size()));
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      NestedTypeRecord &Nested) {
   printTypeIndex("Type", Nested.getNestedType());
   W->printString("Name", Nested.getName());
@@ -592,7 +610,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      OneMethodRecord &Method) {
   MethodKind K = Method.getKind();
   printMemberAttributes(Method.getAccess(), K, Method.getOptions());
@@ -605,7 +623,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      OverloadedMethodRecord &Method) {
   W->printHex("MethodCount", Method.getNumOverloads());
   printTypeIndex("MethodListIndex", Method.getMethodList());
@@ -614,7 +632,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      DataMemberRecord &Field) {
   printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -625,7 +643,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      StaticDataMemberRecord &Field) {
   printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -635,13 +653,13 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      VFPtrRecord &VFTable) {
   printTypeIndex("Type", VFTable.getType());
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      EnumeratorRecord &Enum) {
   printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -651,7 +669,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      BaseClassRecord &Base) {
   printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -660,7 +678,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      VirtualBaseClassRecord &Base) {
   printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -671,7 +689,7 @@ Error CVTypeDumper::visitKnownRecord(CVR
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownMember(CVMemberRecord &CVR,
                                      ListContinuationRecord &Cont) {
   printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
   return Error::success();

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Wed Sep 14 18:00:16 2016
@@ -60,18 +60,18 @@ public:
 
 /// TypeVisitorCallbacks overrides.
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
-      override;
+  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override;
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
-  Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override;
+  Error visitUnknownType(CVType &Record) override;
 
-  Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
-  Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override;
+  Error visitTypeBegin(CVType &Record) override;
+  Error visitTypeEnd(CVType &Record) override;
+  Error visitMemberEnd(CVMemberRecord &Record) override;
 
   bool mergeStream(const CVTypeArray &Types);
 
@@ -137,27 +137,30 @@ Error TypeStreamMerger::visitTypeEnd(CVR
     IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));
     FieldBuilder.reset();
     IsInFieldList = false;
-  } else if (!IsInFieldList) {
-    assert(IndexMap.size() == BeginIndexMapSize + 1);
   }
   return Error::success();
 }
 
+Error TypeStreamMerger::visitMemberEnd(CVMemberRecord &Rec) {
+  assert(IndexMap.size() == BeginIndexMapSize + 1);
+  return Error::success();
+}
+
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error TypeStreamMerger::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,        \
+  Error TypeStreamMerger::visitKnownRecord(CVType &CVR,                        \
                                            Name##Record &Record) {             \
     return visitKnownRecordImpl(Record);                                       \
   }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  Error TypeStreamMerger::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,        \
+  Error TypeStreamMerger::visitKnownMember(CVMemberRecord &CVR,                \
                                            Name##Record &Record) {             \
     return visitKnownMemberRecordImpl(Record);                                 \
   }
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
-Error TypeStreamMerger::visitUnknownType(CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitUnknownType(CVType &Rec) {
   // We failed to translate a type. Translate this index as "not translated".
   IndexMap.push_back(
       TypeIndex(SimpleTypeKind::NotTranslated, SimpleTypeMode::Direct));

Modified: llvm/trunk/lib/DebugInfo/PDB/Raw/TpiHashing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Raw/TpiHashing.cpp?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Raw/TpiHashing.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Raw/TpiHashing.cpp Wed Sep 14 18:00:16 2016
@@ -58,15 +58,15 @@ void TpiHashUpdater::visitKnownRecordImp
 }
 
 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, ClassRecord &Rec) {
-  CVR.Hash = getTpiHash(Rec, CVR.RawData);
+  CVR.Hash = getTpiHash(Rec, CVR.data());
 }
 
 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, EnumRecord &Rec) {
-  CVR.Hash = getTpiHash(Rec, CVR.RawData);
+  CVR.Hash = getTpiHash(Rec, CVR.data());
 }
 
 void TpiHashUpdater::visitKnownRecordImpl(CVType &CVR, UnionRecord &Rec) {
-  CVR.Hash = getTpiHash(Rec, CVR.RawData);
+  CVR.Hash = getTpiHash(Rec, CVR.data());
 }
 
 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, UdtSourceLineRecord &Rec) {
@@ -79,17 +79,17 @@ Error TpiHashVerifier::visitKnownRecord(
 }
 
 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, ClassRecord &Rec) {
-  if (getTpiHash(Rec, CVR.RawData) % NumHashBuckets != HashValues[Index])
+  if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index])
     return errorInvalidHash();
   return Error::success();
 }
 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, EnumRecord &Rec) {
-  if (getTpiHash(Rec, CVR.RawData) % NumHashBuckets != HashValues[Index])
+  if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index])
     return errorInvalidHash();
   return Error::success();
 }
 Error TpiHashVerifier::visitKnownRecord(CVType &CVR, UnionRecord &Rec) {
-  if (getTpiHash(Rec, CVR.RawData) % NumHashBuckets != HashValues[Index])
+  if (getTpiHash(Rec, CVR.data()) % NumHashBuckets != HashValues[Index])
     return errorInvalidHash();
   return Error::success();
 }

Modified: llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.cpp Wed Sep 14 18:00:16 2016
@@ -15,7 +15,9 @@
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeSerializationVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
+#include "llvm/DebugInfo/PDB/Raw/TpiHashing.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
@@ -27,33 +29,33 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRe
 LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
 LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
 LLVM_YAML_IS_SEQUENCE_VECTOR(CVType)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiFieldListRecord)
 
 namespace {
 struct FieldListRecordSplitter : public TypeVisitorCallbacks {
 public:
   explicit FieldListRecordSplitter(
-      std::vector<llvm::pdb::yaml::PdbTpiRecord> &Records)
+      std::vector<llvm::pdb::yaml::PdbTpiFieldListRecord> &Records)
       : Records(Records) {}
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  Error visitKnownRecord(CVType &CVT, Name##Record &Record) override {         \
-    visitKnownRecordImpl(CVT);                                                 \
+  Error visitKnownMember(CVMemberRecord &CVT, Name##Record &Record) override { \
+    visitKnownMemberImpl(CVT);                                                 \
     return Error::success();                                                   \
   }
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
 private:
-  void visitKnownRecordImpl(CVType &CVT) {
-    llvm::pdb::yaml::PdbTpiRecord R;
+  void visitKnownMemberImpl(CVMemberRecord &CVT) {
+    llvm::pdb::yaml::PdbTpiFieldListRecord R;
     R.Record = CVT;
     Records.push_back(std::move(R));
   }
 
-  std::vector<llvm::pdb::yaml::PdbTpiRecord> &Records;
+  std::vector<llvm::pdb::yaml::PdbTpiFieldListRecord> &Records;
 };
 }
 
@@ -525,14 +527,20 @@ void ScalarEnumerationTraits<TypeLeafKin
 }
 
 Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
-    CVRecord<TypeLeafKind> &CVR) {
+    CVType &CVR) {
   YamlIO.mapRequired("Kind", CVR.Type);
   return Error::success();
 }
 
+Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitMemberBegin(
+    CVMemberRecord &Record) {
+  YamlIO.mapRequired("Kind", Record.Kind);
+  return Error::success();
+}
+
 void llvm::codeview::yaml::YamlTypeDumperCallbacks::visitKnownRecordImpl(
     const char *Name, CVType &CVR, FieldListRecord &FieldList) {
-  std::vector<llvm::pdb::yaml::PdbTpiRecord> FieldListRecords;
+  std::vector<llvm::pdb::yaml::PdbTpiFieldListRecord> FieldListRecords;
   if (YamlIO.outputting()) {
     // If we are outputting, then `FieldList.Data` contains a huge chunk of data
     // representing the serialized list of members.  We need to split it up into
@@ -551,3 +559,36 @@ void llvm::codeview::yaml::YamlTypeDumpe
   }
   YamlIO.mapRequired("FieldList", FieldListRecords, Context);
 }
+
+namespace llvm {
+namespace yaml {
+template <>
+struct MappingContextTraits<pdb::yaml::PdbTpiFieldListRecord,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbTpiFieldListRecord &Obj,
+                      pdb::yaml::SerializationContext &Context) {
+    codeview::TypeVisitorCallbackPipeline Pipeline;
+    codeview::TypeDeserializer Deserializer;
+    codeview::TypeSerializationVisitor Serializer(Context.FieldListBuilder,
+                                                  Context.TypeTableBuilder);
+    pdb::TpiHashUpdater Hasher;
+
+    if (IO.outputting()) {
+      // For PDB to Yaml, deserialize into a high level record type, then dump
+      // it.
+      Pipeline.addCallbackToPipeline(Deserializer);
+      Pipeline.addCallbackToPipeline(Context.Dumper);
+    } else {
+      // For Yaml to PDB, extract from the high level record type, then write it
+      // to bytes.
+      Pipeline.addCallbackToPipeline(Context.Dumper);
+      Pipeline.addCallbackToPipeline(Serializer);
+      Pipeline.addCallbackToPipeline(Hasher);
+    }
+
+    codeview::CVTypeVisitor Visitor(Pipeline);
+    consumeError(Visitor.visitMemberRecord(Obj.Record));
+  }
+};
+}
+}

Modified: llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/CodeViewYaml.h Wed Sep 14 18:00:16 2016
@@ -29,7 +29,8 @@ public:
                           llvm::pdb::yaml::SerializationContext &Context)
       : YamlIO(IO), Context(Context) {}
 
-  virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
+  virtual Error visitTypeBegin(CVType &Record) override;
+  virtual Error visitMemberBegin(CVMemberRecord &Record) override;
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
   Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
@@ -38,12 +39,19 @@ public:
     return Error::success();                                                   \
   }
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  TYPE_RECORD(EnumName, EnumVal, Name)
+  Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override { \
+    visitKnownMemberImpl(#Name, Record);                                       \
+    return Error::success();                                                   \
+  }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
 private:
+  template <typename T> void visitKnownMemberImpl(const char *Name, T &Record) {
+    YamlIO.mapRequired(Name, Record);
+  }
+
   template <typename T>
   void visitKnownRecordImpl(const char *Name, CVType &Type, T &Record) {
     YamlIO.mapRequired(Name, Record);

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Wed Sep 14 18:00:16 2016
@@ -497,7 +497,7 @@ Error LLVMOutputStyle::dumpTpiStream(uin
       }
 
       if (DumpRecordBytes)
-        P.printBinaryBlock("Bytes", Type.Data);
+        P.printBinaryBlock("Bytes", Type.content());
     }
     dumpTpiHash(P, *Tpi);
     if (HadError)
@@ -604,7 +604,7 @@ Error LLVMOutputStyle::dumpDbiStream() {
             if (opts::raw::DumpModuleSyms)
               SD.dump(S);
             if (opts::raw::DumpSymRecordBytes)
-              P.printBinaryBlock("Bytes", S.Data);
+              P.printBinaryBlock("Bytes", S.content());
           }
           if (HadError)
             return make_error<RawError>(
@@ -813,7 +813,7 @@ Error LLVMOutputStyle::dumpPublicsStream
 
     SD.dump(S);
     if (opts::raw::DumpSymRecordBytes)
-      P.printBinaryBlock("Bytes", S.Data);
+      P.printBinaryBlock("Bytes", S.content());
   }
   if (HadError)
     return make_error<RawError>(

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.h?rev=281556&r1=281555&r2=281556&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.h Wed Sep 14 18:00:16 2016
@@ -75,6 +75,10 @@ struct PdbTpiRecord {
   codeview::CVType Record;
 };
 
+struct PdbTpiFieldListRecord {
+  codeview::CVMemberRecord Record;
+};
+
 struct PdbTpiStream {
   PdbRaw_TpiVer Version;
   std::vector<PdbTpiRecord> Records;




More information about the llvm-commits mailing list