Resubmit "[pdb] Change type visitor pattern to be dynamic."

There was a regression introduced during type stream merging when
visiting a field list record.  This has been fixed in this patch.

llvm-svn: 272929
diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
index 99e5037..46717f2 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp
@@ -84,39 +84,44 @@
 }
 
 namespace {
-class TpiHashVerifier : public CVTypeVisitor<TpiHashVerifier> {
+class TpiHashVerifier : public TypeVisitorCallbacks {
 public:
   TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues,
                   uint32_t NumHashBuckets)
       : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}
 
-  void visitUdtSourceLine(UdtSourceLineRecord &Rec) { verifySourceLine(Rec); }
-
-  void visitUdtModSourceLine(UdtModSourceLineRecord &Rec) {
-    verifySourceLine(Rec);
+  Error visitUdtSourceLine(UdtSourceLineRecord &Rec) override {
+    return verifySourceLine(Rec);
   }
 
-  void visitClass(ClassRecord &Rec) { verify(Rec); }
-  void visitEnum(EnumRecord &Rec) { verify(Rec); }
-  void visitInterface(ClassRecord &Rec) { verify(Rec); }
-  void visitStruct(ClassRecord &Rec) { verify(Rec); }
-  void visitUnion(UnionRecord &Rec) { verify(Rec); }
+  Error visitUdtModSourceLine(UdtModSourceLineRecord &Rec) override {
+    return verifySourceLine(Rec);
+  }
 
-  void visitTypeEnd(const CVRecord<TypeLeafKind> &Record) { ++Index; }
+  Error visitClass(ClassRecord &Rec) override { return verify(Rec); }
+  Error visitEnum(EnumRecord &Rec) override { return verify(Rec); }
+  Error visitUnion(UnionRecord &Rec) override { return verify(Rec); }
+
+  Error visitTypeEnd(const CVRecord<TypeLeafKind> &Record) override {
+    ++Index;
+    return Error::success();
+  }
 
 private:
-  template <typename T> void verify(T &Rec) {
+  template <typename T> Error verify(T &Rec) {
     uint32_t Hash = getTpiHash(Rec);
     if (Hash && Hash % NumHashBuckets != HashValues[Index])
-      parseError();
+      return make_error<RawError>(raw_error_code::invalid_tpi_hash);
+    return Error::success();
   }
 
-  template <typename T> void verifySourceLine(T &Rec) {
+  template <typename T> Error verifySourceLine(T &Rec) {
     char Buf[4];
     support::endian::write32le(Buf, Rec.getUDT().getIndex());
     uint32_t Hash = hashStringV1(StringRef(Buf, 4));
     if (Hash % NumHashBuckets != HashValues[Index])
-      parseError();
+      return make_error<RawError>(raw_error_code::invalid_tpi_hash);
+    return Error::success();
   }
 
   FixedStreamArray<support::ulittle32_t> HashValues;
@@ -129,11 +134,8 @@
 // Currently we only verify SRC_LINE records.
 Error TpiStream::verifyHashValues() {
   TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
-  Verifier.visitTypeStream(TypeRecords);
-  if (Verifier.hadError())
-    return make_error<RawError>(raw_error_code::corrupt_file,
-                                "Corrupt TPI hash table.");
-  return Error::success();
+  CVTypeVisitor Visitor(Verifier);
+  return Visitor.visitTypeStream(TypeRecords);
 }
 
 Error TpiStream::reload() {