[codeview] Have visitTypeBegin return the record type.
authorZachary Turner <zturner@google.com>
Wed, 31 Aug 2016 23:14:31 +0000 (23:14 +0000)
committerZachary Turner <zturner@google.com>
Wed, 31 Aug 2016 23:14:31 +0000 (23:14 +0000)
Previously we were assuming that any visitation of types would
necessarily be against a type we had binary data for.  Reasonable
assumption when were just reading PDBs and dumping them, but once
we start writing PDBs from Yaml this breaks down, because we have
no binary data yet, only Yaml, and from that we need to read the
record kind and perform the switch based on that.

So this patch does that.  Instead of having the visitor switch
on the kind that is already in the CVType record, we change the
visitTypeBegin() method to return the Kind, and switch on the
returned value.  This way, the default implementation can still
return the value from the CVType, but the implementation which
visits Yaml records and serializes binary PDB type records can
use the field in the Yaml as the source of the switch.

llvm-svn: 280307

llvm/include/llvm/DebugInfo/CodeView/TypeDumper.h
llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
llvm/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
llvm/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
llvm/lib/DebugInfo/CodeView/TypeDumper.cpp
llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
llvm/tools/llvm-pdbdump/CodeViewYaml.cpp
llvm/tools/llvm-pdbdump/CodeViewYaml.h

index 49db43d6b7bb9c06c8cde6bfb92ff62792f021d9..598f97047808be80cc7eb49c7a5eba17294b1c1d 100644 (file)
@@ -68,7 +68,8 @@ public:
 
   /// Paired begin/end actions for all types. Receives all record data,
   /// including the fixed-length record prefix.
-  Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
+  Expected<TypeLeafKind>
+  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
   Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
index 3bfd52d4da44d135f4e790bcaadf576cc04f2a01..d158f42947c97c79d8acef9609b961d5e1439c7b 100644 (file)
@@ -40,12 +40,16 @@ public:
     return Error::success();
   }
 
-  virtual Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {
+  virtual Expected<TypeLeafKind>
+  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override {
+    TypeLeafKind Kind = Record.Type;
     for (auto Visitor : Pipeline) {
-      if (auto EC = Visitor->visitTypeBegin(Record))
-        return EC;
+      if (auto ExpectedKind = Visitor->visitTypeBegin(Record))
+        Kind = *ExpectedKind;
+      else
+        return ExpectedKind.takeError();
     }
-    return Error::success();
+    return Kind;
   }
   virtual Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
     for (auto Visitor : Pipeline) {
index a734d480fe39d03bb6f3f32d2b4088e87a82af8c..ecae9eef807b39248ab69f62b1cfb7b95c662faf 100644 (file)
@@ -33,9 +33,11 @@ public:
   }
 
   /// Paired begin/end actions for all types. Receives all record data,
-  /// including the fixed-length record prefix.
-  virtual Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
-    return Error::success();
+  /// 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 visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
     return Error::success();
index 18215d355820e4cf296ab3877f2897551dc3c237..b4c3a9f4c21e712b9e9f028c85495315e6c0cc19 100644 (file)
@@ -75,10 +75,13 @@ static Error visitKnownRecord(const CVRecord<TypeLeafKind> &Record,
 }
 
 Error CVTypeVisitor::visitTypeRecord(const CVRecord<TypeLeafKind> &Record) {
-  if (auto EC = Callbacks.visitTypeBegin(Record))
-    return EC;
+  TypeLeafKind Kind;
+  if (auto ExpectedKind = Callbacks.visitTypeBegin(Record))
+    Kind = *ExpectedKind;
+  else
+    return ExpectedKind.takeError();
 
-  switch (Record.Type) {
+  switch (Kind) {
   default:
     if (auto EC = Callbacks.visitUnknownType(Record))
       return EC;
@@ -133,8 +136,9 @@ Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
     if (!ExpectedRecord)                                                       \
       return ExpectedRecord.takeError();                                       \
     auto &Record = *ExpectedRecord;                                            \
-    if (auto EC = Callbacks.visitTypeBegin(Record))                            \
-      return EC;                                                               \
+    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))                              \
index f7dfdd2f3986bffdb9ed36b313aa361bf33ea487..43e29b7f451ff55c5601a7c2246b9033ec96b04c 100644 (file)
@@ -203,7 +203,8 @@ static StringRef getLeafTypeName(TypeLeafKind LT) {
   return "UnknownLeaf";
 }
 
-Error CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
+Expected<TypeLeafKind>
+CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
   // Reset Name to the empty string. If the visitor sets it, we know it.
   Name = "";
 
@@ -223,7 +224,7 @@ Error CVTypeDumper::visitTypeBegin(const CVRecord<TypeLeafKind> &Record) {
     assert(!IsInFieldList);
     IsInFieldList = true;
   }
-  return Error::success();
+  return Record.Type;
 }
 
 Error CVTypeDumper::visitTypeEnd(const CVRecord<TypeLeafKind> &Record) {
index ddc3f4af58e4a24bccd0ae1c72cdad7a0b047057..f2a7298a8d1d250831d4b0fe8dd813f8b0e9a203 100644 (file)
@@ -70,7 +70,8 @@ public:
 
   Error visitUnknownType(const CVRecord<TypeLeafKind> &Record) override;
 
-  Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
+  Expected<TypeLeafKind>
+  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
   Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override;
 
   bool mergeStream(const CVTypeArray &Types);
@@ -123,13 +124,14 @@ private:
 
 } // end anonymous namespace
 
-Error TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {
+Expected<TypeLeafKind>
+TypeStreamMerger::visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) {
   if (Rec.Type == TypeLeafKind::LF_FIELDLIST) {
     assert(!IsInFieldList);
     IsInFieldList = true;
   } else
     BeginIndexMapSize = IndexMap.size();
-  return Error::success();
+  return Rec.Type;
 }
 
 Error TypeStreamMerger::visitTypeEnd(const CVRecord<TypeLeafKind> &Rec) {
index 74200e70119c87efad3d77d958e2e69d3df5afdb..7154b297b124ca3efd7b5ff7d785c5da7d1a2a21 100644 (file)
@@ -121,10 +121,11 @@ public:
     return verify(Rec);
   }
 
-  Error visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
+  Expected<TypeLeafKind>
+  visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
     ++Index;
     RawRecord = &Rec;
-    return Error::success();
+    return Rec.Type;
   }
 
 private:
index 96bf1c19aa6b3d2d989afebaca93b9c6b5fad8c2..e75f454b34a9734ac3bffe1c7601167d88625983 100644 (file)
@@ -508,9 +508,13 @@ void ScalarEnumerationTraits<TypeLeafKind>::enumeration(IO &io,
 }
 }
 
-Error llvm::codeview::yaml::YamlTypeDumperCallbacks::visitTypeBegin(
+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 Error::success();
+  return K;
 }
index bacb55cef40797d099498e0699e23af8bc3cff22..8932d008ca38e5cc1ce9228d2421556343a7e98b 100644 (file)
@@ -21,7 +21,8 @@ class YamlTypeDumperCallbacks : public TypeVisitorCallbacks {
 public:
   YamlTypeDumperCallbacks(llvm::yaml::IO &IO) : YamlIO(IO) {}
 
-  virtual Error visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
+  virtual Expected<TypeLeafKind>
+  visitTypeBegin(const CVRecord<TypeLeafKind> &Record) override;
 
 #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
   Error visitKnownRecord(const CVRecord<TypeLeafKind> &CVR,                    \