[pdb] Pass CVRecord's through the visitor as non-const references.
authorZachary Turner <zturner@google.com>
Fri, 9 Sep 2016 18:03:39 +0000 (18:03 +0000)
committerZachary Turner <zturner@google.com>
Fri, 9 Sep 2016 18:03:39 +0000 (18:03 +0000)
This simplifies a lot of code, and will actually be necessary for
an upcoming patch to serialize TPI record hash values.

The idea before was that visitors should be examining records, not
modifying them.  But this is no longer true with a visitor that
constructs a CVRecord from Yaml.  To handle this until now, we
were doing some fixups on CVRecord objects at a higher level, but
the code is really awkward, and it makes sense to just have the
visitor write the bytes into the CVRecord.  In doing so I uncovered
a few bugs related to `Data` and `RawData` and fixed those.

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

llvm-svn: 281067

15 files changed:
llvm/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
llvm/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
llvm/include/llvm/DebugInfo/CodeView/TypeDumper.h
llvm/include/llvm/DebugInfo/CodeView/TypeSerializationVisitor.h
llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
llvm/include/llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h
llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
llvm/lib/DebugInfo/CodeView/TypeTableBuilder.cpp
llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
llvm/tools/llvm-pdbdump/CodeViewYaml.cpp
llvm/tools/llvm-pdbdump/CodeViewYaml.h
llvm/tools/llvm-pdbdump/PdbYaml.cpp

index 668db5c..7c26327 100644 (file)
@@ -23,7 +23,7 @@ class CVTypeVisitor {
 public:
   explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
 
-  Error visitTypeRecord(const CVRecord<TypeLeafKind> &Record);
+  Error visitTypeRecord(CVRecord<TypeLeafKind> &Record);
 
   /// Visits the type records in Data. Sets the error flag on parse failures.
   Error visitTypeStream(const CVTypeArray &Types);
index 27d9e59..fa3a67e 100644 (file)
@@ -20,8 +20,8 @@ public:
   TypeDeserializer() {}
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
-                         Name##Record &Record) override {                      \
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
+      override {                                                               \
     return defaultVisitKnownRecord(CVR, Record);                               \
   }
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
@@ -45,7 +45,7 @@ protected:
 
 private:
   template <typename T>
-  Error defaultVisitKnownRecord(const CVRecord<TypeLeafKind> &CVR, T &Record) {
+  Error defaultVisitKnownRecord(CVRecord<TypeLeafKind> &CVR, T &Record) {
     ArrayRef<uint8_t> RD = CVR.Data;
     if (auto EC = deserializeRecord(RD, CVR.Type, Record))
       return EC;
index 598f970..e431f1a 100644 (file)
@@ -63,18 +63,17 @@ public:
   ScopedPrinter *getPrinter() { return W; }
 
   /// Action to take on unknown types. By default, they are ignored.
-  Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
-  Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override;
+  Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override;
+  Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) override;
 
   /// Paired begin/end actions for all types. Receives all record data,
   /// including the fixed-length record prefix.
-  Expected<TypeLeafKind>
-  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
-  Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
+  Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
+  Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override;
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
-                         Name##Record &Record) override;
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
+      override;
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
   TYPE_RECORD(EnumName, EnumVal, Name)
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
index d752f27..e6f2859 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
 
 namespace llvm {
 namespace codeview {
@@ -26,27 +27,35 @@ public:
       : FieldListBuilder(FieldListBuilder), TypeTableBuilder(TypeTableBuilder) {
   }
 
-  virtual Expected<TypeLeafKind> visitTypeBegin(const CVType &Record) override {
+  virtual Error visitTypeBegin(CVType &Record) override {
     if (Record.Type == TypeLeafKind::LF_FIELDLIST)
       FieldListBuilder.reset();
-    return Record.Type;
+    return Error::success();
   }
 
-  virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitTypeEnd(CVType &Record) override {
+    // Since this visitor's purpose is to serialize the record, fill out the
+    // fields of `Record` with the bytes of the record.
     if (Record.Type == TypeLeafKind::LF_FIELDLIST)
       TypeTableBuilder.writeFieldList(FieldListBuilder);
+
+    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);
     return Error::success();
   }
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,            \
+  virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,                  \
                                  Name##Record &Record) override {              \
     visitKnownRecordImpl(Record);                                              \
     return Error::success();                                                   \
   }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,            \
+  virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,                  \
                                  Name##Record &Record) override {              \
     visitMemberRecordImpl(Record);                                             \
     return Error::success();                                                   \
index e604233..a625302 100644 (file)
@@ -22,8 +22,7 @@ class TypeVisitorCallbackPipeline : public TypeVisitorCallbacks {
 public:
   TypeVisitorCallbackPipeline() {}
 
-  virtual Error
-  visitUnknownType(const CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override {
     for (auto Visitor : Pipeline) {
       if (auto EC = Visitor->visitUnknownType(Record))
         return EC;
@@ -31,8 +30,7 @@ public:
     return Error::success();
   }
 
-  virtual Error
-  visitUnknownMember(const CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitUnknownMember(CVRecord<TypeLeafKind> &Record) override {
     for (auto Visitor : Pipeline) {
       if (auto EC = Visitor->visitUnknownMember(Record))
         return EC;
@@ -40,23 +38,14 @@ public:
     return Error::success();
   }
 
-  virtual Expected<TypeLeafKind>
-  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {
-    // An implementation can calculate of visitTypeBegin() can calculate the
-    // kind based on an arbitrary factor, including the Type that is already
-    // specified in the Record.  So, as we go through the pipeline invoking
-    // each visitor, update the state in a copy of the record so that each
-    // visitor in the pipeline sees the most recently value of the type.
-    CVRecord<TypeLeafKind> RecordCopy = Record;
+  virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override {
     for (auto Visitor : Pipeline) {
-      if (auto ExpectedKind = Visitor->visitTypeBegin(RecordCopy)) {
-        RecordCopy.Type = *ExpectedKind;
-      } else
-        return ExpectedKind.takeError();
+      if (auto EC = Visitor->visitTypeBegin(Record))
+        return EC;
     }
-    return RecordCopy.Type;
+    return Error::success();
   }
-  virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
+  virtual Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override {
     for (auto Visitor : Pipeline) {
       if (auto EC = Visitor->visitTypeEnd(Record))
         return EC;
@@ -69,8 +58,8 @@ public:
   }
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
-                         Name##Record &Record) override {                      \
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
+      override {                                                               \
     for (auto Visitor : Pipeline) {                                            \
       if (auto EC = Visitor->visitKnownRecord(CVR, Record))                    \
         return EC;                                                             \
index ecae9ee..a97ad74 100644 (file)
@@ -25,26 +25,25 @@ public:
   virtual ~TypeVisitorCallbacks() {}
 
   /// Action to take on unknown types. By default, they are ignored.
-  virtual Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
+  virtual Error visitUnknownType(CVRecord<TypeLeafKind> &Record) {
     return Error::success();
   }
-  virtual Error visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
+  virtual Error visitUnknownMember(CVRecord<TypeLeafKind> &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 Expected<TypeLeafKind>
-  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
-    return Record.Type;
+  virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
+    return Error::success();
   }
-  virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+  virtual Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) {
     return Error::success();
   }
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  virtual Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,            \
+  virtual Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,                  \
                                  Name##Record &Record) {                       \
     return Error::success();                                                   \
   }
index 5aca1d4..ec3a5e3 100644 (file)
@@ -30,7 +30,9 @@ class ReadableStreamRef;
 class WritableStream;
 
 template <> struct SequencedItemTraits<llvm::codeview::CVType> {
-  static size_t length(const codeview::CVType &Item) { return Item.Length; }
+  static size_t length(const codeview::CVType &Item) {
+    return Item.RawData.size();
+  }
   static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) {
     return Item.RawData;
   }
index f14a49c..cdcc837 100644 (file)
@@ -65,7 +65,7 @@ CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
     : Callbacks(Callbacks) {}
 
 template <typename T>
-static Error visitKnownRecord(const CVRecord<TypeLeafKind> &Record,
+static Error visitKnownRecord(CVRecord<TypeLeafKind> &Record,
                               TypeVisitorCallbacks &Callbacks) {
   TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type);
   T KnownRecord(RK);
@@ -74,24 +74,18 @@ static Error visitKnownRecord(const CVRecord<TypeLeafKind> &Record,
   return Error::success();
 }
 
-Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
-  TypeLeafKind Kind;
-  if (auto ExpectedKind = Callbacks.visitTypeBegin(Record))
-    Kind = *ExpectedKind;
-  else
-    return ExpectedKind.takeError();
-
-  CVType RecordCopy = Record;
-  RecordCopy.Type = Kind;
+Error CVTypeVisitor::visitTypeRecord(CVRecord<TypeLeafKind> &Record) {
+  if (auto EC = Callbacks.visitTypeBegin(Record))
+    return EC;
 
-  switch (Kind) {
+  switch (Record.Type) {
   default:
-    if (auto EC = Callbacks.visitUnknownType(RecordCopy))
+    if (auto EC = Callbacks.visitUnknownType(Record))
       return EC;
     break;
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
   case EnumName: {                                                             \
-    if (auto EC = visitKnownRecord<Name##Record>(RecordCopy, Callbacks))       \
+    if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks))           \
       return EC;                                                               \
     break;                                                                     \
   }
@@ -104,7 +98,7 @@ Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
   }
 
-  if (auto EC = Callbacks.visitTypeEnd(RecordCopy))
+  if (auto EC = Callbacks.visitTypeEnd(Record))
     return EC;
 
   return Error::success();
@@ -112,13 +106,29 @@ Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
 
 /// Visits the type records in Data. Sets the error flag on parse failures.
 Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
-  for (const auto &I : Types) {
+  for (auto I : Types) {
     if (auto EC = visitTypeRecord(I))
       return EC;
   }
   return Error::success();
 }
 
+template <typename MR>
+static Error visitKnownMember(ArrayRef<uint8_t> &Data, TypeLeafKind Leaf,
+                              TypeVisitorCallbacks &Callbacks) {
+  auto ExpectedRecord = deserializeMemberRecord<MR>(Data, Leaf);
+  if (!ExpectedRecord)
+    return ExpectedRecord.takeError();
+  CVType &Record = *ExpectedRecord;
+  if (auto EC = Callbacks.visitTypeBegin(Record))
+    return EC;
+  if (auto EC = visitKnownRecord<MR>(Record, Callbacks))
+    return EC;
+  if (auto EC = Callbacks.visitTypeEnd(Record))
+    return EC;
+  return Error::success();
+}
+
 Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
   while (!Data.empty()) {
     const support::ulittle16_t *LeafValue;
@@ -135,16 +145,7 @@ Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
           cv_error_code::unknown_member_record);
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
   case EnumName: {                                                             \
-    auto ExpectedRecord = deserializeMemberRecord<Name##Record>(Data, Leaf);   \
-    if (!ExpectedRecord)                                                       \
-      return ExpectedRecord.takeError();                                       \
-    auto &Record = *ExpectedRecord;                                            \
-    auto ExpectedKind = Callbacks.visitTypeBegin(Record);                      \
-    if (!ExpectedKind || *ExpectedKind != Leaf)                                \
-      return ExpectedKind.takeError();                                         \
-    if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks))           \
-      return EC;                                                               \
-    if (auto EC = Callbacks.visitTypeEnd(Record))                              \
+    if (auto EC = visitKnownMember<Name##Record>(Data, Leaf, Callbacks))       \
       return EC;                                                               \
     break;                                                                     \
   }
index 43e29b7..db805c5 100644 (file)
@@ -203,8 +203,7 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
   return "UnknownLeaf";
 }
 
-Expected<TypeLeafKind>
-CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitTypeBegin(CVRecord<TypeLeafKind> &Record) {
   // Reset Name to the empty string. If the visitor sets it, we know it.
   Name = "";
 
@@ -224,10 +223,10 @@ CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
     assert(!IsInFieldList);
     IsInFieldList = true;
   }
-  return Record.Type;
+  return Error::success();
 }
 
-Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitTypeEnd(CVRecord<TypeLeafKind> &Record) {
   if (Record.Type == LF_FIELDLIST) {
     assert(IsInFieldList);
     IsInFieldList = false;
@@ -249,7 +248,7 @@ Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      FieldListRecord &FieldList) {
   TypeDeserializer Deserializer;
   TypeVisitorCallbackPipeline Pipeline;
@@ -264,7 +263,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      StringIdRecord &String) {
   printTypeIndex("Id", String.getId());
   W->printString("StringData", String.getString());
@@ -273,7 +272,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      ArgListRecord &Args) {
   auto Indices = Args.getIndices();
   uint32_t Size = Indices.size();
@@ -292,7 +291,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      ClassRecord &Class) {
   uint16_t Props = static_cast<uint16_t>(Class.getOptions());
   W->printNumber("MemberCount", Class.getMemberCount());
@@ -308,7 +307,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      UnionRecord &Union) {
   uint16_t Props = static_cast<uint16_t>(Union.getOptions());
   W->printNumber("MemberCount", Union.getMemberCount());
@@ -322,7 +321,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      EnumRecord &Enum) {
   uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
   W->printNumber("NumEnumerators", Enum.getMemberCount());
@@ -337,7 +336,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      ArrayRecord &AT) {
   printTypeIndex("ElementType", AT.getElementType());
   printTypeIndex("IndexType", AT.getIndexType());
@@ -347,7 +346,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      VFTableRecord &VFT) {
   printTypeIndex("CompleteClass", VFT.getCompleteClass());
   printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
@@ -359,7 +358,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      MemberFuncIdRecord &Id) {
   printTypeIndex("ClassType", Id.getClassType());
   printTypeIndex("FunctionType", Id.getFunctionType());
@@ -368,7 +367,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      ProcedureRecord &Proc) {
   printTypeIndex("ReturnType", Proc.getReturnType());
   W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
@@ -387,7 +386,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      MemberFunctionRecord &MF) {
   printTypeIndex("ReturnType", MF.getReturnType());
   printTypeIndex("ClassType", MF.getClassType());
@@ -412,7 +411,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      MethodOverloadListRecord &MethodList) {
   for (auto &M : MethodList.getMethods()) {
     ListScope S(*W, "Method");
@@ -424,7 +423,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      FuncIdRecord &Func) {
   printTypeIndex("ParentScope", Func.getParentScope());
   printTypeIndex("FunctionType", Func.getFunctionType());
@@ -433,7 +432,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      TypeServer2Record &TS) {
   W->printBinary("Signature", TS.getGuid());
   W->printNumber("Age", TS.getAge());
@@ -442,7 +441,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      PointerRecord &Ptr) {
   printTypeIndex("PointeeType", Ptr.getReferentType());
   W->printHex("PointerAttributes", uint32_t(Ptr.getOptions()));
@@ -494,7 +493,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      ModifierRecord &Mod) {
   uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
   printTypeIndex("ModifiedType", Mod.getModifiedType());
@@ -513,7 +512,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      BitFieldRecord &BitField) {
   printTypeIndex("Type", BitField.getType());
   W->printNumber("BitSize", BitField.getBitSize());
@@ -521,14 +520,14 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      VFTableShapeRecord &Shape) {
   W->printNumber("VFEntryCount", Shape.getEntryCount());
   Name = saveName("<vftable " + utostr(Shape.getEntryCount()) + " methods>");
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      UdtSourceLineRecord &Line) {
   printTypeIndex("UDT", Line.getUDT());
   printTypeIndex("SourceFile", Line.getSourceFile());
@@ -536,7 +535,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      UdtModSourceLineRecord &Line) {
   printTypeIndex("UDT", Line.getUDT());
   printTypeIndex("SourceFile", Line.getSourceFile());
@@ -545,7 +544,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      BuildInfoRecord &Args) {
   W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
 
@@ -574,18 +573,18 @@ void CVTypeDumper::printMemberAttributes(MemberAccess Access, MethodKind Kind,
   }
 }
 
-Error CVTypeDumper::visitUnknownMember(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitUnknownMember(CVRecord<TypeLeafKind> &Record) {
   W->printHex("UnknownMember", unsigned(Record.Type));
   return Error::success();
 }
 
-Error CVTypeDumper::visitUnknownType(const CVRecord<TypeLeafKind> &Record) {
+Error CVTypeDumper::visitUnknownType(CVRecord<TypeLeafKind> &Record) {
   W->printEnum("Kind", uint16_t(Record.Type), makeArrayRef(LeafTypeNames));
   W->printNumber("Length", uint32_t(Record.Data.size()));
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      NestedTypeRecord &Nested) {
   printTypeIndex("Type", Nested.getNestedType());
   W->printString("Name", Nested.getName());
@@ -593,7 +592,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      OneMethodRecord &Method) {
   MethodKind K = Method.getKind();
   printMemberAttributes(Method.getAccess(), K, Method.getOptions());
@@ -606,7 +605,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      OverloadedMethodRecord &Method) {
   W->printHex("MethodCount", Method.getNumOverloads());
   printTypeIndex("MethodListIndex", Method.getMethodList());
@@ -615,7 +614,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      DataMemberRecord &Field) {
   printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -626,7 +625,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      StaticDataMemberRecord &Field) {
   printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -636,13 +635,13 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      VFPtrRecord &VFTable) {
   printTypeIndex("Type", VFTable.getType());
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      EnumeratorRecord &Enum) {
   printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -652,7 +651,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      BaseClassRecord &Base) {
   printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -661,7 +660,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      VirtualBaseClassRecord &Base) {
   printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
                         MethodOptions::None);
@@ -672,7 +671,7 @@ Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
   return Error::success();
 }
 
-Error CVTypeDumper::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+Error CVTypeDumper::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                                      ListContinuationRecord &Cont) {
   printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
   return Error::success();
@@ -724,7 +723,8 @@ Error CVTypeDumper::dump(const CVRecord<TypeLeafKind> &Record) {
 
   CVTypeVisitor Visitor(Pipeline);
 
-  if (auto EC = Visitor.visitTypeRecord(Record))
+  CVRecord<TypeLeafKind> RecordCopy = Record;
+  if (auto EC = Visitor.visitTypeRecord(RecordCopy))
     return EC;
   return Error::success();
 }
index f2a7298..096fd38 100644 (file)
@@ -60,19 +60,18 @@ public:
 
 /// TypeVisitorCallbacks overrides.
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
-                         Name##Record &Record) override;
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
+      override;
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
   TYPE_RECORD(EnumName, EnumVal, Name)
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
-  Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
+  Error visitUnknownType(CVRecord<TypeLeafKind> &Record) override;
 
-  Expected<TypeLeafKind>
-  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
-  Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
+  Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
+  Error visitTypeEnd(CVRecord<TypeLeafKind> &Record) override;
 
   bool mergeStream(const CVTypeArray &Types);
 
@@ -124,17 +123,16 @@ private:
 
 } // end anonymous namespace
 
-Expected<TypeLeafKind>
-TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitTypeBegin(CVRecord<TypeLeafKind> &Rec) {
   if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
     assert(!IsInFieldList);
     IsInFieldList = true;
   } else
     BeginIndexMapSize = IndexMap.size();
-  return Rec.Type;
+  return Error::success();
 }
 
-Error TypeStreamMerger::visitTypeEnd(const CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitTypeEnd(CVRecord<TypeLeafKind> &Rec) {
   if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
     IndexMap.push_back(DestStream.writeFieldList(FieldBuilder));
     FieldBuilder.reset();
@@ -146,20 +144,20 @@ Error TypeStreamMerger::visitTypeEnd(const CVRecord<TypeLeafKind> &Rec) {
 }
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error TypeStreamMerger::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,  \
+  Error TypeStreamMerger::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,        \
                                            Name##Record &Record) {             \
     return visitKnownRecordImpl(Record);                                       \
   }
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  Error TypeStreamMerger::visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,  \
+  Error TypeStreamMerger::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,        \
                                            Name##Record &Record) {             \
     return visitKnownMemberRecordImpl(Record);                                 \
   }
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
-Error TypeStreamMerger::visitUnknownType(const CVRecord<TypeLeafKind> &Rec) {
+Error TypeStreamMerger::visitUnknownType(CVRecord<TypeLeafKind> &Rec) {
   // We failed to translate a type. Translate this index as "not translated".
   IndexMap.push_back(
       TypeIndex(SimpleTypeKind::NotTranslated, SimpleTypeMode::Direct));
index 45b9b3f..03f8b1d 100644 (file)
@@ -263,7 +263,9 @@ TypeIndex TypeTableBuilder::writeRecord(TypeRecordBuilder &Builder) {
 }
 
 TypeIndex TypeTableBuilder::writeFieldList(FieldListRecordBuilder &FieldList) {
-  return FieldList.writeListRecord(*this);
+  TypeIndex I = FieldList.writeListRecord(*this);
+  RecordKinds.push_back(TypeRecordKind::FieldList);
+  return I;
 }
 
 TypeIndex
index ce645eb..5560643 100644 (file)
@@ -69,34 +69,33 @@ public:
                   uint32_t NumHashBuckets)
       : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
 
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                          UdtSourceLineRecord &Rec) override {
     return verifySourceLine(Rec);
   }
 
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                          UdtModSourceLineRecord &Rec) override {
     return verifySourceLine(Rec);
   }
 
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                          ClassRecord &Rec) override {
     return verify(Rec);
   }
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                          EnumRecord &Rec) override {
     return verify(Rec);
   }
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
                          UnionRecord &Rec) override {
     return verify(Rec);
   }
 
-  Expected<TypeLeafKind>
-  visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
+  Error visitTypeBegin(CVRecord<TypeLeafKind> &Rec) override {
     ++Index;
     RawRecord = Rec;
-    return Rec.Type;
+    return Error::success();
   }
 
 private:
index 2b3bf50..d480815 100644 (file)
@@ -40,14 +40,14 @@ public:
 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
 #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
-  Error visitKnownRecord(const CVType &CVT, Name##Record &Record) override {   \
+  Error visitKnownRecord(CVType &CVT, Name##Record &Record) override {         \
     visitKnownRecordImpl(CVT);                                                 \
     return Error::success();                                                   \
   }
 #include "llvm/DebugInfo/CodeView/TypeRecords.def"
 
 private:
-  void visitKnownRecordImpl(const CVType &CVT) {
+  void visitKnownRecordImpl(CVType &CVT) {
     llvm::pdb::yaml::PdbTpiRecord R;
     R.Record = CVT;
     Records.push_back(std::move(R));
@@ -524,19 +524,14 @@ void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
 }
 }
 
-Expected<TypeLeafKind>
-llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
-    const CVRecord<TypeLeafKind> &CVR) {
-  // When we're outputting, `CVR.Type` already has the right value in it.  But
-  // when we're inputting, we need to read the value.  Since `CVR.Type` is const
-  // we do it into a temp variable.
-  TypeLeafKind K = CVR.Type;
-  YamlIO.mapRequired("Kind", K);
-  return K;
+Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
+    CVRecord<TypeLeafKind> &CVR) {
+  YamlIO.mapRequired("Kind", CVR.Type);
+  return Error::success();
 }
 
 void llvm::codeview::yaml::YamlTypeDumperCallbacks::visitKnownRecordImpl(
-    const char *Name, const CVType &CVR, FieldListRecord &FieldList) {
+    const char *Name, CVType &CVR, FieldListRecord &FieldList) {
   std::vector<llvm::pdb::yaml::PdbTpiRecord> FieldListRecords;
   if (YamlIO.outputting()) {
     // If we are outputting, then `FieldList.Data` contains a huge chunk of data
index 78dbf5e..0c0c66b 100644 (file)
@@ -29,12 +29,11 @@ public:
                           llvm::pdb::yaml::SerializationContext &Context)
       : YamlIO(IO), Context(Context) {}
 
-  virtual Expected<TypeLeafKind>
-  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
+  virtual Error visitTypeBegin(CVRecord<TypeLeafKind> &Record) override;
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
-  Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \
-                         Name##Record &Record) override {                      \
+  Error visitKnownRecord(CVRecord<TypeLeafKind> &CVR, Name##Record &Record)    \
+      override {                                                               \
     visitKnownRecordImpl(#Name, CVR, Record);                                  \
     return Error::success();                                                   \
   }
@@ -46,11 +45,11 @@ public:
 
 private:
   template <typename T>
-  void visitKnownRecordImpl(const char *Name, const CVType &Type, T &Record) {
+  void visitKnownRecordImpl(const char *Name, CVType &Type, T &Record) {
     YamlIO.mapRequired(Name, Record);
   }
 
-  void visitKnownRecordImpl(const char *Name, const CVType &CVR,
+  void visitKnownRecordImpl(const char *Name, CVType &CVR,
                             FieldListRecord &FieldList);
 
   llvm::yaml::IO &YamlIO;
index 1884edf..6b59720 100644 (file)
@@ -230,19 +230,4 @@ void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
 
   codeview::CVTypeVisitor Visitor(Pipeline);
   consumeError(Visitor.visitTypeRecord(Obj.Record));
-
-  if (!IO.outputting()) {
-    // For Yaml to PDB, we need to update the input Object with the bytes for
-    // this record.
-    ArrayRef<StringRef> Records = Context.TypeTableBuilder.getRecords();
-    ArrayRef<codeview::TypeRecordKind> Kinds =
-        Context.TypeTableBuilder.getRecordKinds();
-
-    StringRef ThisRecord = Records.back();
-    Obj.Record.Type = static_cast<codeview::TypeLeafKind>(Kinds.back());
-    Obj.Record.Data =
-        ArrayRef<uint8_t>(ThisRecord.bytes_begin(), ThisRecord.bytes_end());
-    Obj.Record.RawData = Obj.Record.Data;
-    Obj.Record.Length = ThisRecord.size();
-  }
 }