[llvm] r303409 - Revert "[CodeView] Provide a common interface for type collections."

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu May 18 22:57:45 PDT 2017


Author: zturner
Date: Fri May 19 00:57:45 2017
New Revision: 303409

URL: http://llvm.org/viewvc/llvm-project?rev=303409&view=rev
Log:
Revert "[CodeView] Provide a common interface for type collections."

This is a squash of ~5 reverts of, well, pretty much everything
I did today.  Something is seriously broken with lit on Windows
right now, and as a result assertions that fire in tests are
triggering failures.  I've been breaking non-Windows bots all
day which has seriously confused me because all my tests have
been passing, and after running lit with -a to view the output
even on successful runs, I find out that the tool is crashing
and yet lit is still reporting it as a success!

At this point I don't even know where to start, so rather than
leave the tree broken for who knows how long, I will get this
back to green, and then once lit is fixed on Windows, hopefully
hopefully fix the remaining set of problems for real.

Added:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h
    llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp
Removed:
    llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeCollection.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
    llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeIndex.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDatabase.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
    llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDatabase.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
    llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/tools/llvm-pdbdump/Analyze.cpp
    llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
    llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.h
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
    llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h
    llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp

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=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Fri May 19 00:57:45 2017
@@ -32,10 +32,6 @@ public:
   uint32_t length() const { return RecordData.size(); }
   Kind kind() const { return Type; }
   ArrayRef<uint8_t> data() const { return RecordData; }
-  StringRef str_data() const {
-    return StringRef(reinterpret_cast<const char *>(RecordData.data()),
-                     RecordData.size());
-  }
 
   ArrayRef<uint8_t> content() const {
     return RecordData.drop_front(sizeof(RecordPrefix));

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeDumper.h?rev=303409&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeDumper.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeDumper.h Fri May 19 00:57:45 2017
@@ -0,0 +1,61 @@
+//===-- CVTypeDumper.h - CodeView type info dumper --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
+#define LLVM_DEBUGINFO_CODEVIEW_CVTYPEDUMPER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+namespace llvm {
+
+namespace codeview {
+
+class TypeServerHandler;
+
+/// Dumper for CodeView type streams found in COFF object files and PDB files.
+class CVTypeDumper {
+public:
+  explicit CVTypeDumper(TypeDatabase &TypeDB,
+                        TypeServerHandler *Handler = nullptr)
+      : TypeDB(TypeDB), Handler(Handler) {}
+
+  /// Dumps one type record.  Returns false if there was a type parsing error,
+  /// and true otherwise.  This should be called in order, since the dumper
+  /// maintains state about previous records which are necessary for cross
+  /// type references.
+  Error dump(const CVType &Record, TypeVisitorCallbacks &Dumper);
+
+  /// Dumps the type records in Types. Returns false if there was a type stream
+  /// parse error, and true otherwise.
+  Error dump(const CVTypeArray &Types, TypeVisitorCallbacks &Dumper);
+
+  /// Dumps the type records in Data. Returns false if there was a type stream
+  /// parse error, and true otherwise. Use this method instead of the
+  /// CVTypeArray overload when type records are laid out contiguously in
+  /// memory.
+  Error dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper);
+
+  static void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
+                             TypeIndex TI, TypeDatabase &DB);
+
+private:
+  TypeDatabase &TypeDB;
+  TypeServerHandler *Handler;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H

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=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h Fri May 19 00:57:45 2017
@@ -10,15 +10,42 @@
 #ifndef LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
 #define LLVM_DEBUGINFO_CODEVIEW_CVTYPEVISITOR_H
 
+#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/DebugInfo/CodeView/CVRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 #include "llvm/Support/Error.h"
 
 namespace llvm {
 namespace codeview {
-class TypeCollection;
-class TypeServerHandler;
-class TypeVisitorCallbacks;
+
+class CVTypeVisitor {
+public:
+  explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
+
+  void addTypeServerHandler(TypeServerHandler &Handler);
+
+  Error visitTypeRecord(CVType &Record, TypeIndex Index);
+  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);
+  Error visitTypeStream(CVTypeRange Types);
+
+  Error visitFieldListMemberStream(ArrayRef<uint8_t> FieldList);
+  Error visitFieldListMemberStream(BinaryStreamReader Reader);
+
+private:
+  Expected<bool> handleTypeServer(CVType &Record);
+  Error finishVisitation(CVType &Record);
+
+  /// The interface to the class that gets notified of each visitation.
+  TypeVisitorCallbacks &Callbacks;
+
+  TinyPtrVector<TypeServerHandler *> Handlers;
+};
 
 enum VisitorDataSource {
   VDS_BytesPresent, // The record bytes are passed into the the visitation
@@ -49,8 +76,6 @@ Error visitTypeStream(const CVTypeArray
                       TypeServerHandler *TS = nullptr);
 Error visitTypeStream(CVTypeRange Types, TypeVisitorCallbacks &Callbacks,
                       TypeServerHandler *TS = nullptr);
-Error visitTypeStream(TypeCollection &Types, TypeVisitorCallbacks &Callbacks,
-                      TypeServerHandler *TS = nullptr);
 
 } // end namespace codeview
 } // end namespace llvm

Removed: llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h?rev=303408&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h (removed)
@@ -1,103 +0,0 @@
-//===- LazyRandomTypeCollection.h ---------------------------- *- C++ --*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
-#define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H
-
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace codeview {
-
-class TypeDatabase;
-class TypeVisitorCallbacks;
-
-/// \brief Provides amortized O(1) random access to a CodeView type stream.
-/// Normally to access a type from a type stream, you must know its byte
-/// offset into the type stream, because type records are variable-lengthed.
-/// However, this is not the way we prefer to access them.  For example, given
-/// a symbol record one of the fields may be the TypeIndex of the symbol's
-/// type record.  Or given a type record such as an array type, there might
-/// be a TypeIndex for the element type.  Sequential access is perfect when
-/// we're just dumping every entry, but it's very poor for real world usage.
-///
-/// Type streams in PDBs contain an additional field which is a list of pairs
-/// containing indices and their corresponding offsets, roughly every ~8KB of
-/// record data.  This general idea need not be confined to PDBs though.  By
-/// supplying such an array, the producer of a type stream can allow the
-/// consumer much better access time, because the consumer can find the nearest
-/// index in this array, and do a linear scan forward only from there.
-///
-/// LazyRandomTypeCollection implements this algorithm, but additionally goes
-/// one step further by caching offsets of every record that has been visited at
-/// least once.  This way, even repeated visits of the same record will never
-/// require more than one linear scan.  For a type stream of N elements divided
-/// into M chunks of roughly equal size, this yields a worst case lookup time
-/// of O(N/M) and an amortized time of O(1).
-class LazyRandomTypeCollection : public TypeCollection {
-  typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray;
-
-public:
-  explicit LazyRandomTypeCollection(uint32_t RecordCountHint);
-  LazyRandomTypeCollection(StringRef Data, uint32_t RecordCountHint);
-  LazyRandomTypeCollection(ArrayRef<uint8_t> Data, uint32_t RecordCountHint);
-  LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint,
-                           PartialOffsetArray PartialOffsets);
-  LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint);
-
-  void reset(ArrayRef<uint8_t> Data);
-  void reset(StringRef Data);
-
-  CVType getType(TypeIndex Index) override;
-  StringRef getTypeName(TypeIndex Index) override;
-  bool contains(TypeIndex Index) override;
-  uint32_t size() override;
-  uint32_t capacity() override;
-  TypeIndex getFirst() override;
-  Optional<TypeIndex> getNext(TypeIndex Prev) override;
-
-private:
-  const TypeDatabase &database() const { return Database; }
-  Error ensureTypeExists(TypeIndex Index);
-
-  Error visitRangeForType(TypeIndex TI);
-  Error fullScanForType(TypeIndex TI);
-  Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
-  Error visitOneRecord(TypeIndex TI, uint32_t Offset, CVType &Record);
-
-  /// Visited records get automatically added to the type database.
-  TypeDatabase Database;
-
-  /// The type array to allow random access visitation of.
-  CVTypeArray Types;
-
-  /// The database visitor which adds new records to the database.
-  TypeDatabaseVisitor DatabaseVisitor;
-
-  /// A vector mapping type indices to type offset.  For every record that has
-  /// been visited, contains the absolute offset of that record in the record
-  /// array.
-  std::vector<uint32_t> KnownOffsets;
-
-  /// An array of index offsets for the given type stream, allowing log(N)
-  /// lookups of a type record by index.  Similar to KnownOffsets but only
-  /// contains offsets for some type indices, some of which may not have
-  /// ever been visited.
-  PartialOffsetArray PartialOffsets;
-};
-
-} // end namespace codeview
-} // end namespace llvm
-
-#endif // LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H

Added: llvm/trunk/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h?rev=303409&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h Fri May 19 00:57:45 2017
@@ -0,0 +1,88 @@
+//===- RandomAccessTypeVisitor.h ------------------------------ *- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H
+#define LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H
+
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+class TypeDatabase;
+class TypeServerHandler;
+class TypeVisitorCallbacks;
+
+/// \brief Provides amortized O(1) random access to a CodeView type stream.
+/// Normally to access a type from a type stream, you must know its byte
+/// offset into the type stream, because type records are variable-lengthed.
+/// However, this is not the way we prefer to access them.  For example, given
+/// a symbol record one of the fields may be the TypeIndex of the symbol's
+/// type record.  Or given a type record such as an array type, there might
+/// be a TypeIndex for the element type.  Sequential access is perfect when
+/// we're just dumping every entry, but it's very poor for real world usage.
+///
+/// Type streams in PDBs contain an additional field which is a list of pairs
+/// containing indices and their corresponding offsets, roughly every ~8KB of
+/// record data.  This general idea need not be confined to PDBs though.  By
+/// supplying such an array, the producer of a type stream can allow the
+/// consumer much better access time, because the consumer can find the nearest
+/// index in this array, and do a linear scan forward only from there.
+///
+/// RandomAccessTypeVisitor implements this algorithm, but additionally goes one
+/// step further by caching offsets of every record that has been visited at
+/// least once.  This way, even repeated visits of the same record will never
+/// require more than one linear scan.  For a type stream of N elements divided
+/// into M chunks of roughly equal size, this yields a worst case lookup time
+/// of O(N/M) and an amortized time of O(1).
+class RandomAccessTypeVisitor {
+  typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray;
+
+public:
+  RandomAccessTypeVisitor(const CVTypeArray &Types, uint32_t NumRecords,
+                          PartialOffsetArray PartialOffsets);
+
+  Error visitTypeIndex(TypeIndex Index, TypeVisitorCallbacks &Callbacks);
+
+  const TypeDatabase &database() const { return Database; }
+
+private:
+  Error visitRangeForType(TypeIndex TI);
+  Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End);
+
+  /// Visited records get automatically added to the type database.
+  TypeDatabase Database;
+
+  /// The type array to allow random access visitation of.
+  const CVTypeArray &Types;
+
+  /// The database visitor which adds new records to the database.
+  TypeDatabaseVisitor DatabaseVisitor;
+
+  /// A vector mapping type indices to type offset.  For every record that has
+  /// been visited, contains the absolute offset of that record in the record
+  /// array.
+  std::vector<uint32_t> KnownOffsets;
+
+  /// An array of index offsets for the given type stream, allowing log(N)
+  /// lookups of a type record by index.  Similar to KnownOffsets but only
+  /// contains offsets for some type indices, some of which may not have
+  /// ever been visited.
+  PartialOffsetArray PartialOffsets;
+};
+
+} // end namespace codeview
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_RANDOMACCESSTYPEVISITOR_H

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/SymbolDumper.h Fri May 19 00:57:45 2017
@@ -20,15 +20,15 @@ namespace llvm {
 class ScopedPrinter;
 
 namespace codeview {
-class TypeCollection;
+class TypeDatabase;
 
 /// Dumper for CodeView symbol streams found in COFF object files and PDB files.
 class CVSymbolDumper {
 public:
-  CVSymbolDumper(ScopedPrinter &W, TypeCollection &Types,
+  CVSymbolDumper(ScopedPrinter &W, TypeDatabase &TypeDB,
                  std::unique_ptr<SymbolDumpDelegate> ObjDelegate,
                  bool PrintRecordBytes)
-      : W(W), Types(Types), ObjDelegate(std::move(ObjDelegate)),
+      : W(W), TypeDB(TypeDB), ObjDelegate(std::move(ObjDelegate)),
         PrintRecordBytes(PrintRecordBytes) {}
 
   /// Dumps one type record.  Returns false if there was a type parsing error,
@@ -43,7 +43,7 @@ public:
 
 private:
   ScopedPrinter &W;
-  TypeCollection &Types;
+  TypeDatabase &TypeDB;
   std::unique_ptr<SymbolDumpDelegate> ObjDelegate;
 
   bool PrintRecordBytes;

Removed: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeCollection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeCollection.h?rev=303408&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeCollection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeCollection.h (removed)
@@ -1,38 +0,0 @@
-//===- TypeCollection.h - A collection of CodeView type records -*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPECOLLECTION_H
-
-#include "llvm/ADT/StringRef.h"
-
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-
-namespace llvm {
-namespace codeview {
-class TypeCollection {
-public:
-  virtual ~TypeCollection() = default;
-
-  bool empty() { return size() == 0; }
-
-  virtual TypeIndex getFirst() = 0;
-  virtual Optional<TypeIndex> getNext(TypeIndex Prev) = 0;
-
-  virtual CVType getType(TypeIndex Index) = 0;
-  virtual StringRef getTypeName(TypeIndex Index) = 0;
-  virtual bool contains(TypeIndex Index) = 0;
-  virtual uint32_t size() = 0;
-  virtual uint32_t capacity() = 0;
-};
-}
-}
-
-#endif

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDatabase.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDatabase.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDatabase.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDatabase.h Fri May 19 00:57:45 2017
@@ -13,7 +13,6 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/Support/Allocator.h"
@@ -21,7 +20,7 @@
 
 namespace llvm {
 namespace codeview {
-class TypeDatabase : public TypeCollection {
+class TypeDatabase {
   friend class RandomAccessTypeVisitor;
 
 public:
@@ -42,31 +41,19 @@ public:
   CVType &getTypeRecord(TypeIndex Index);
 
   bool contains(TypeIndex Index) const;
+
   uint32_t size() const;
   uint32_t capacity() const;
   bool empty() const;
 
-  CVType getType(TypeIndex Index) override;
-  StringRef getTypeName(TypeIndex Index) override;
-  bool contains(TypeIndex Index) override;
-  uint32_t size() override;
-  uint32_t capacity() override;
-
-  TypeIndex getFirst() override;
-  Optional<TypeIndex> getNext(TypeIndex Prev) override;
-
-  Optional<TypeIndex> largestTypeIndexLessThan(TypeIndex TI) const;
-
-private:
   TypeIndex getAppendIndex() const;
 
+private:
   void grow();
-  void grow(TypeIndex Index);
 
   BumpPtrAllocator Allocator;
 
   uint32_t Count = 0;
-  TypeIndex LargestTypeIndex;
 
   /// All user defined type records in .debug$T live in here. Type indices
   /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h Fri May 19 00:57:45 2017
@@ -12,6 +12,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
@@ -21,20 +22,17 @@ class ScopedPrinter;
 
 namespace codeview {
 
-class TypeCollection;
-
 /// Dumper for CodeView type streams found in COFF object files and PDB files.
 class TypeDumpVisitor : public TypeVisitorCallbacks {
 public:
-  TypeDumpVisitor(TypeCollection &TpiTypes, ScopedPrinter *W,
-                  bool PrintRecordBytes)
-      : W(W), PrintRecordBytes(PrintRecordBytes), TpiTypes(TpiTypes) {}
+  TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes)
+      : W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {}
 
   /// When dumping types from an IPI stream in a PDB, a type index may refer to
   /// a type or an item ID. The dumper will lookup the "name" of the index in
   /// the item database if appropriate. If ItemDB is null, it will use TypeDB,
   /// which is correct when dumping types from an object file (/Z7).
-  void setIpiTypes(TypeCollection &Types) { IpiTypes = &Types; }
+  void setItemDB(TypeDatabase &DB) { ItemDB = &DB; }
 
   void printTypeIndex(StringRef FieldName, TypeIndex TI) const;
 
@@ -68,16 +66,14 @@ private:
   /// Get the database of indices for the stream that we are dumping. If ItemDB
   /// is set, then we must be dumping an item (IPI) stream. This will also
   /// always get the appropriate DB for printing item names.
-  TypeCollection &getSourceTypes() const {
-    return IpiTypes ? *IpiTypes : TpiTypes;
-  }
+  TypeDatabase &getSourceDB() const { return ItemDB ? *ItemDB : TypeDB; }
 
   ScopedPrinter *W;
 
   bool PrintRecordBytes = false;
 
-  TypeCollection &TpiTypes;
-  TypeCollection *IpiTypes = nullptr;
+  TypeDatabase &TypeDB;
+  TypeDatabase *ItemDB = nullptr;
 };
 
 } // end namespace codeview

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h Fri May 19 00:57:45 2017
@@ -15,13 +15,8 @@
 #include <cinttypes>
 
 namespace llvm {
-
-class ScopedPrinter;
-
 namespace codeview {
 
-class TypeCollection;
-
 enum class SimpleTypeKind : uint32_t {
   None = 0x0000,          // uncharacterized type (no type)
   Void = 0x0003,          // void
@@ -243,11 +238,6 @@ public:
     return Result;
   }
 
-  friend inline uint32_t operator-(const TypeIndex &A, const TypeIndex &B) {
-    assert(A >= B);
-    return A.toArrayIndex() - B.toArrayIndex();
-  }
-
 private:
   support::ulittle32_t Index;
 };
@@ -259,9 +249,6 @@ struct TypeIndexOffset {
   TypeIndex Type;
   support::ulittle32_t Offset;
 };
-
-void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI,
-                    TypeCollection &Types);
 }
 }
 

Removed: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h?rev=303408&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeTableCollection.h (removed)
@@ -1,42 +0,0 @@
-//===- TypeTableCollection.h ---------------------------------- *- C++ --*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H
-#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H
-
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
-
-namespace llvm {
-namespace codeview {
-
-class TypeTableCollection : public TypeCollection {
-public:
-  explicit TypeTableCollection(ArrayRef<MutableArrayRef<uint8_t>> Records);
-
-  TypeIndex getFirst() override;
-  Optional<TypeIndex> getNext(TypeIndex Prev) override;
-
-  CVType getType(TypeIndex Index) override;
-  StringRef getTypeName(TypeIndex Index) override;
-  bool contains(TypeIndex Index) override;
-  uint32_t size() override;
-  uint32_t capacity() override;
-
-private:
-  bool hasCapacityFor(TypeIndex Index) const;
-  void ensureTypeExists(TypeIndex Index);
-
-  ArrayRef<MutableArrayRef<uint8_t>> Records;
-  TypeDatabase Database;
-};
-}
-}
-
-#endif

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=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h Fri May 19 00:57:45 2017
@@ -17,6 +17,8 @@ namespace llvm {
 namespace codeview {
 
 class TypeVisitorCallbacks {
+  friend class CVTypeVisitor;
+
 public:
   virtual ~TypeVisitorCallbacks() = default;
 

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h Fri May 19 00:57:45 2017
@@ -13,6 +13,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri May 19 00:57:45 2017
@@ -13,6 +13,7 @@
 
 #include "CodeViewDebug.h"
 #include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
@@ -22,7 +23,6 @@
 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -469,21 +469,17 @@ void CodeViewDebug::emitTypeInformation(
     CommentPrefix += ' ';
   }
 
-  TypeTableCollection Table(TypeTable.records());
-  Optional<TypeIndex> B = Table.getFirst();
-  do {
-    // This will fail if the record data is invalid.
-    CVType Record = Table.getType(*B);
-
+  TypeDatabase TypeDB(TypeTable.records().size());
+  CVTypeDumper CVTD(TypeDB);
+  TypeTable.ForEachRecord([&](TypeIndex Index, ArrayRef<uint8_t> Record) {
     if (OS.isVerboseAsm()) {
       // Emit a block comment describing the type record for readability.
       SmallString<512> CommentBlock;
       raw_svector_ostream CommentOS(CommentBlock);
       ScopedPrinter SP(CommentOS);
       SP.setPrefix(CommentPrefix);
-      TypeDumpVisitor TDV(Table, &SP, false);
-
-      Error E = codeview::visitTypeRecord(Record, *B, TDV);
+      TypeDumpVisitor TDV(TypeDB, &SP, false);
+      Error E = CVTD.dump(Record, TDV);
       if (E) {
         logAllUnhandledErrors(std::move(E), errs(), "error: ");
         llvm_unreachable("produced malformed type record");
@@ -493,9 +489,29 @@ void CodeViewDebug::emitTypeInformation(
       // newline.
       OS.emitRawComment(
           CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim());
+    } else {
+#ifndef NDEBUG
+      // Assert that the type data is valid even if we aren't dumping
+      // comments. The MSVC linker doesn't do much type record validation,
+      // so the first link of an invalid type record can succeed while
+      // subsequent links will fail with LNK1285.
+      BinaryByteStream Stream(Record, llvm::support::little);
+      CVTypeArray Types;
+      BinaryStreamReader Reader(Stream);
+      Error E = Reader.readArray(Types, Reader.getLength());
+      if (!E) {
+        TypeVisitorCallbacks C;
+        E = codeview::visitTypeStream(Types, C);
+      }
+      if (E) {
+        logAllUnhandledErrors(std::move(E), errs(), "error: ");
+        llvm_unreachable("produced malformed type record");
+      }
+#endif
     }
-    OS.EmitBinaryData(Record.str_data());
-  } while ((B = Table.getNext(*B)));
+    StringRef S(reinterpret_cast<const char *>(Record.data()), Record.size());
+    OS.EmitBinaryData(S);
+  });
 }
 
 namespace {

Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Fri May 19 00:57:45 2017
@@ -2,10 +2,10 @@ add_llvm_library(LLVMDebugInfoCodeView
   CodeViewError.cpp
   CodeViewRecordIO.cpp
   CVSymbolVisitor.cpp
+  CVTypeDumper.cpp
   CVTypeVisitor.cpp
   EnumTables.cpp
   Formatters.cpp
-  LazyRandomTypeCollection.cpp
   Line.cpp
   ModuleDebugFileChecksumFragment.cpp
   ModuleDebugFragment.cpp
@@ -13,6 +13,7 @@ add_llvm_library(LLVMDebugInfoCodeView
   ModuleDebugFragmentVisitor.cpp
   ModuleDebugInlineeLinesFragment.cpp
   ModuleDebugLineFragment.cpp
+  RandomAccessTypeVisitor.cpp
   RecordSerialization.cpp
   StringTable.cpp
   SymbolRecordMapping.cpp
@@ -21,12 +22,10 @@ add_llvm_library(LLVMDebugInfoCodeView
   TypeDatabase.cpp
   TypeDatabaseVisitor.cpp
   TypeDumpVisitor.cpp
-  TypeIndex.cpp
   TypeRecordMapping.cpp
   TypeSerializer.cpp
   TypeStreamMerger.cpp
-  TypeTableCollection.cpp
-  
+
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/CodeView
   )

Added: llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp?rev=303409&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeDumper.cpp Fri May 19 00:57:45 2017
@@ -0,0 +1,61 @@
+//===-- CVTypeDumper.cpp - CodeView type info dumper ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
+#include "llvm/Support/BinaryByteStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error CVTypeDumper::dump(const CVType &Record, TypeVisitorCallbacks &Dumper) {
+  TypeDatabaseVisitor DBV(TypeDB);
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(DBV);
+  Pipeline.addCallbackToPipeline(Dumper);
+
+  CVType RecordCopy = Record;
+  return codeview::visitTypeRecord(RecordCopy, Pipeline, VDS_BytesPresent,
+                                   Handler);
+}
+
+Error CVTypeDumper::dump(const CVTypeArray &Types,
+                         TypeVisitorCallbacks &Dumper) {
+  TypeDatabaseVisitor DBV(TypeDB);
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(DBV);
+  Pipeline.addCallbackToPipeline(Dumper);
+
+  return codeview::visitTypeStream(Types, Pipeline, Handler);
+}
+
+Error CVTypeDumper::dump(ArrayRef<uint8_t> Data, TypeVisitorCallbacks &Dumper) {
+  BinaryByteStream Stream(Data, llvm::support::little);
+  CVTypeArray Types;
+  BinaryStreamReader Reader(Stream);
+  if (auto EC = Reader.readArray(Types, Reader.getLength()))
+    return EC;
+
+  return dump(Types, Dumper);
+}
+
+void CVTypeDumper::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
+                                  TypeIndex TI, TypeDatabase &DB) {
+  StringRef TypeName;
+  if (!TI.isNoneType())
+    TypeName = DB.getTypeName(TI);
+  if (!TypeName.empty())
+    Printer.printHex(FieldName, TypeName, TI.getIndex());
+  else
+    Printer.printHex(FieldName, TI.getIndex());
+}

Modified: llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/CVTypeVisitor.cpp Fri May 19 00:57:45 2017
@@ -9,9 +9,7 @@
 
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 
-#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
@@ -24,6 +22,8 @@
 using namespace llvm;
 using namespace llvm::codeview;
 
+CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
+    : Callbacks(Callbacks) {}
 
 template <typename T>
 static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
@@ -66,67 +66,6 @@ static Expected<TypeServer2Record> deser
   return R;
 }
 
-static Error visitMemberRecord(CVMemberRecord &Record,
-                               TypeVisitorCallbacks &Callbacks) {
-  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)                                 \
-  case EnumName: {                                                             \
-    if (auto EC = visitKnownMember<Name##Record>(Record, Callbacks))           \
-      return EC;                                                               \
-    break;                                                                     \
-  }
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, 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.visitMemberEnd(Record))
-    return EC;
-
-  return Error::success();
-}
-
-namespace {
-
-class CVTypeVisitor {
-public:
-  explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
-
-  void addTypeServerHandler(TypeServerHandler &Handler);
-
-  Error visitTypeRecord(CVType &Record, TypeIndex Index);
-  Error visitTypeRecord(CVType &Record);
-
-  /// Visits the type records in Data. Sets the error flag on parse failures.
-  Error visitTypeStream(const CVTypeArray &Types);
-  Error visitTypeStream(CVTypeRange Types);
-  Error visitTypeStream(TypeCollection &Types);
-
-  Error visitMemberRecord(CVMemberRecord Record);
-  Error visitFieldListMemberStream(BinaryStreamReader &Stream);
-
-private:
-  Expected<bool> handleTypeServer(CVType &Record);
-  Error finishVisitation(CVType &Record);
-
-  /// The interface to the class that gets notified of each visitation.
-  TypeVisitorCallbacks &Callbacks;
-
-  TinyPtrVector<TypeServerHandler *> Handlers;
-};
-
-CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
-    : Callbacks(Callbacks) {}
-
 void CVTypeVisitor::addTypeServerHandler(TypeServerHandler &Handler) {
   Handlers.push_back(&Handler);
 }
@@ -205,6 +144,35 @@ Error CVTypeVisitor::visitTypeRecord(CVT
   return finishVisitation(Record);
 }
 
+static Error visitMemberRecord(CVMemberRecord &Record,
+                               TypeVisitorCallbacks &Callbacks) {
+  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)                                 \
+  case EnumName: {                                                             \
+    if (auto EC = visitKnownMember<Name##Record>(Record, Callbacks))           \
+      return EC;                                                               \
+    break;                                                                     \
+  }
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, 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.visitMemberEnd(Record))
+    return EC;
+
+  return Error::success();
+}
+
 Error CVTypeVisitor::visitMemberRecord(CVMemberRecord Record) {
   return ::visitMemberRecord(Record, Callbacks);
 }
@@ -226,20 +194,12 @@ Error CVTypeVisitor::visitTypeStream(CVT
   return Error::success();
 }
 
-Error CVTypeVisitor::visitTypeStream(TypeCollection &Types) {
-  if (Types.empty())
-    return Error::success();
-
-  Optional<TypeIndex> I = Types.getFirst();
-  do {
-    CVType Type = Types.getType(*I);
-    if (auto EC = visitTypeRecord(Type, *I))
-      return EC;
-  } while ((I = Types.getNext(*I)));
-  return Error::success();
-}
+Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader Reader) {
+  FieldListDeserializer Deserializer(Reader);
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(Deserializer);
+  Pipeline.addCallbackToPipeline(Callbacks);
 
-Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader &Reader) {
   TypeLeafKind Leaf;
   while (!Reader.empty()) {
     if (auto EC = Reader.readEnum(Leaf))
@@ -247,13 +207,20 @@ Error CVTypeVisitor::visitFieldListMembe
 
     CVMemberRecord Record;
     Record.Kind = Leaf;
-    if (auto EC = ::visitMemberRecord(Record, Callbacks))
+    if (auto EC = ::visitMemberRecord(Record, Pipeline))
       return EC;
   }
 
   return Error::success();
 }
 
+Error CVTypeVisitor::visitFieldListMemberStream(ArrayRef<uint8_t> Data) {
+  BinaryByteStream S(Data, llvm::support::little);
+  BinaryStreamReader SR(S);
+  return visitFieldListMemberStream(SR);
+}
+
+namespace {
 struct FieldListVisitHelper {
   FieldListVisitHelper(TypeVisitorCallbacks &Callbacks, ArrayRef<uint8_t> Data,
                        VisitorDataSource Source)
@@ -274,8 +241,11 @@ struct FieldListVisitHelper {
 };
 
 struct VisitHelper {
-  VisitHelper(TypeVisitorCallbacks &Callbacks, VisitorDataSource Source)
+  VisitHelper(TypeVisitorCallbacks &Callbacks, VisitorDataSource Source,
+              TypeServerHandler *TS)
       : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
+    if (TS)
+      Visitor.addTypeServerHandler(*TS);
     if (Source == VDS_BytesPresent) {
       Pipeline.addCallbackToPipeline(Deserializer);
       Pipeline.addCallbackToPipeline(Callbacks);
@@ -292,57 +262,29 @@ Error llvm::codeview::visitTypeRecord(CV
                                       TypeVisitorCallbacks &Callbacks,
                                       VisitorDataSource Source,
                                       TypeServerHandler *TS) {
-  VisitHelper V(Callbacks, Source);
-  if (TS)
-    V.Visitor.addTypeServerHandler(*TS);
-  return V.Visitor.visitTypeRecord(Record, Index);
+  VisitHelper Helper(Callbacks, Source, TS);
+  return Helper.Visitor.visitTypeRecord(Record, Index);
 }
 
 Error llvm::codeview::visitTypeRecord(CVType &Record,
                                       TypeVisitorCallbacks &Callbacks,
                                       VisitorDataSource Source,
                                       TypeServerHandler *TS) {
-  VisitHelper V(Callbacks, Source);
-  if (TS)
-    V.Visitor.addTypeServerHandler(*TS);
-  return V.Visitor.visitTypeRecord(Record);
-}
-
-Error llvm::codeview::visitTypeStream(const CVTypeArray &Types,
-                                      TypeVisitorCallbacks &Callbacks,
-                                      TypeServerHandler *TS) {
-  VisitHelper V(Callbacks, VDS_BytesPresent);
-  if (TS)
-    V.Visitor.addTypeServerHandler(*TS);
-  return V.Visitor.visitTypeStream(Types);
+  VisitHelper Helper(Callbacks, Source, TS);
+  return Helper.Visitor.visitTypeRecord(Record);
 }
 
-Error llvm::codeview::visitTypeStream(CVTypeRange Types,
-                                      TypeVisitorCallbacks &Callbacks,
-                                      TypeServerHandler *TS) {
-  VisitHelper V(Callbacks, VDS_BytesPresent);
-  if (TS)
-    V.Visitor.addTypeServerHandler(*TS);
-  return V.Visitor.visitTypeStream(Types);
-}
-
-Error llvm::codeview::visitTypeStream(TypeCollection &Types,
-                                      TypeVisitorCallbacks &Callbacks,
-                                      TypeServerHandler *TS) {
-  // When the internal visitor calls Types.getType(Index) the interface is
-  // required to return a CVType with the bytes filled out.  So we can assume
-  // that the bytes will be present when individual records are visited.
-  VisitHelper V(Callbacks, VDS_BytesPresent);
-  if (TS)
-    V.Visitor.addTypeServerHandler(*TS);
-  return V.Visitor.visitTypeStream(Types);
+Error llvm::codeview::visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
+                                              TypeVisitorCallbacks &Callbacks) {
+  CVTypeVisitor Visitor(Callbacks);
+  return Visitor.visitFieldListMemberStream(FieldList);
 }
 
 Error llvm::codeview::visitMemberRecord(CVMemberRecord Record,
                                         TypeVisitorCallbacks &Callbacks,
                                         VisitorDataSource Source) {
-  FieldListVisitHelper V(Callbacks, Record.Data, Source);
-  return V.Visitor.visitMemberRecord(Record);
+  FieldListVisitHelper Helper(Callbacks, Record.Data, Source);
+  return Helper.Visitor.visitMemberRecord(Record);
 }
 
 Error llvm::codeview::visitMemberRecord(TypeLeafKind Kind,
@@ -354,8 +296,16 @@ Error llvm::codeview::visitMemberRecord(
   return visitMemberRecord(R, Callbacks, VDS_BytesPresent);
 }
 
-Error llvm::codeview::visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
-                                              TypeVisitorCallbacks &Callbacks) {
-  FieldListVisitHelper V(Callbacks, FieldList, VDS_BytesPresent);
-  return V.Visitor.visitFieldListMemberStream(V.Reader);
+Error llvm::codeview::visitTypeStream(const CVTypeArray &Types,
+                                      TypeVisitorCallbacks &Callbacks,
+                                      TypeServerHandler *TS) {
+  VisitHelper Helper(Callbacks, VDS_BytesPresent, TS);
+  return Helper.Visitor.visitTypeStream(Types);
+}
+
+Error llvm::codeview::visitTypeStream(CVTypeRange Types,
+                                      TypeVisitorCallbacks &Callbacks,
+                                      TypeServerHandler *TS) {
+  VisitHelper Helper(Callbacks, VDS_BytesPresent, TS);
+  return Helper.Visitor.visitTypeStream(Types);
 }

Removed: llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp?rev=303408&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp (removed)
@@ -1,226 +0,0 @@
-//===- LazyRandomTypeCollection.cpp ---------------------------- *- C++--*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
-#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static void error(Error &&EC) {
-  assert(!static_cast<bool>(EC));
-  if (EC)
-    consumeError(std::move(EC));
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(uint32_t RecordCountHint)
-    : LazyRandomTypeCollection(CVTypeArray(), RecordCountHint,
-                               PartialOffsetArray()) {}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(
-    const CVTypeArray &Types, uint32_t RecordCountHint,
-    PartialOffsetArray PartialOffsets)
-    : Database(RecordCountHint), Types(Types), DatabaseVisitor(Database),
-      PartialOffsets(PartialOffsets) {
-  KnownOffsets.resize(Database.capacity());
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(ArrayRef<uint8_t> Data,
-                                                   uint32_t RecordCountHint)
-    : LazyRandomTypeCollection(RecordCountHint) {
-  reset(Data);
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(StringRef Data,
-                                                   uint32_t RecordCountHint)
-    : LazyRandomTypeCollection(
-          makeArrayRef(Data.bytes_begin(), Data.bytes_end()), RecordCountHint) {
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(const CVTypeArray &Types,
-                                                   uint32_t NumRecords)
-    : LazyRandomTypeCollection(Types, NumRecords, PartialOffsetArray()) {}
-
-void LazyRandomTypeCollection::reset(StringRef Data) {
-  reset(makeArrayRef(Data.bytes_begin(), Data.bytes_end()));
-}
-
-void LazyRandomTypeCollection::reset(ArrayRef<uint8_t> Data) {
-  PartialOffsets = PartialOffsetArray();
-
-  BinaryStreamReader Reader(Data, support::little);
-  error(Reader.readArray(Types, Reader.getLength()));
-
-  KnownOffsets.resize(Database.capacity());
-}
-
-CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
-  error(ensureTypeExists(Index));
-  return Database.getTypeRecord(Index);
-}
-
-StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
-  if (!Index.isSimple()) {
-    // Try to make sure the type exists.  Even if it doesn't though, it may be
-    // because we're dumping a symbol stream with no corresponding type stream
-    // present, in which case we still want to be able to print <unknown UDT>
-    // for the type names.
-    consumeError(ensureTypeExists(Index));
-  }
-
-  return Database.getTypeName(Index);
-}
-
-bool LazyRandomTypeCollection::contains(TypeIndex Index) {
-  return Database.contains(Index);
-}
-
-uint32_t LazyRandomTypeCollection::size() { return Database.size(); }
-
-uint32_t LazyRandomTypeCollection::capacity() { return Database.capacity(); }
-
-Error LazyRandomTypeCollection::ensureTypeExists(TypeIndex TI) {
-  if (!Database.contains(TI)) {
-    if (auto EC = visitRangeForType(TI))
-      return EC;
-  }
-  return Error::success();
-}
-
-Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
-  if (PartialOffsets.empty())
-    return fullScanForType(TI);
-
-  auto Next = std::upper_bound(PartialOffsets.begin(), PartialOffsets.end(), TI,
-                               [](TypeIndex Value, const TypeIndexOffset &IO) {
-                                 return Value < IO.Type;
-                               });
-
-  assert(Next != PartialOffsets.begin());
-  auto Prev = std::prev(Next);
-
-  TypeIndex TIB = Prev->Type;
-  if (Database.contains(TIB)) {
-    // They've asked us to fetch a type index, but the entry we found in the
-    // partial offsets array has already been visited.  Since we visit an entire
-    // block every time, that means this record should have been previously
-    // discovered.  Ultimately, this means this is a request for a non-existant
-    // type index.
-    return make_error<CodeViewError>("Invalid type index");
-  }
-
-  TypeIndex TIE;
-  if (Next == PartialOffsets.end()) {
-    TIE = TypeIndex::fromArrayIndex(Database.capacity());
-  } else {
-    TIE = Next->Type;
-  }
-
-  if (auto EC = visitRange(TIB, Prev->Offset, TIE))
-    return EC;
-  return Error::success();
-}
-
-TypeIndex LazyRandomTypeCollection::getFirst() {
-  TypeIndex TI = TypeIndex::fromArrayIndex(0);
-  error(ensureTypeExists(TI));
-  return TI;
-}
-
-Optional<TypeIndex> LazyRandomTypeCollection::getNext(TypeIndex Prev) {
-  // We can't be sure how long this type stream is, given that the initial count
-  // given to the constructor is just a hint.  So just try to make sure the next
-  // record exists, and if anything goes wrong, we must be at the end.
-  if (auto EC = ensureTypeExists(Prev + 1)) {
-    consumeError(std::move(EC));
-    return None;
-  }
-
-  return Prev + 1;
-}
-
-Error LazyRandomTypeCollection::fullScanForType(TypeIndex TI) {
-  assert(PartialOffsets.empty());
-
-  TypeIndex CurrentTI = TypeIndex::fromArrayIndex(0);
-  uint32_t Offset = 0;
-  auto Begin = Types.begin();
-
-  if (!Database.empty()) {
-    // In the case of type streams which we don't know the number of records of,
-    // it's possible to search for a type index triggering a full scan, but then
-    // later additional records are added since we didn't know how many there
-    // would be until we did a full visitation, then you try to access the new
-    // type triggering another full scan.  To avoid this, we assume that if the
-    // database has some records, this must be what's going on.  So we ask the
-    // database for the largest type index less than the one we're searching for
-    // and only do the forward scan from there.
-    auto Prev = Database.largestTypeIndexLessThan(TI);
-    assert(Prev.hasValue() && "Empty database with valid types?");
-    Offset = KnownOffsets[Prev->toArrayIndex()];
-    CurrentTI = *Prev;
-    ++CurrentTI;
-    Begin = Types.at(Offset);
-    ++Begin;
-    Offset = Begin.offset();
-  }
-
-  auto End = Types.end();
-  while (Begin != End) {
-    if (auto EC = visitOneRecord(CurrentTI, Offset, *Begin))
-      return EC;
-
-    Offset += Begin.getRecordLength();
-    ++Begin;
-    ++CurrentTI;
-  }
-  if (CurrentTI <= TI) {
-    return make_error<CodeViewError>("Type Index does not exist!");
-  }
-  return Error::success();
-}
-
-Error LazyRandomTypeCollection::visitRange(TypeIndex Begin,
-                                           uint32_t BeginOffset,
-                                           TypeIndex End) {
-
-  auto RI = Types.at(BeginOffset);
-  assert(RI != Types.end());
-
-  while (Begin != End) {
-    if (auto EC = visitOneRecord(Begin, BeginOffset, *RI))
-      return EC;
-
-    BeginOffset += RI.getRecordLength();
-    ++Begin;
-    ++RI;
-  }
-
-  return Error::success();
-}
-
-Error LazyRandomTypeCollection::visitOneRecord(TypeIndex TI, uint32_t Offset,
-                                               CVType &Record) {
-  assert(!Database.contains(TI));
-  if (auto EC = codeview::visitTypeRecord(Record, TI, DatabaseVisitor))
-    return EC;
-  // Keep the KnownOffsets array the same size as the Database's capacity. Since
-  // we don't always know how many records are in the type stream, we need to be
-  // prepared for the database growing and receicing a type index that can't fit
-  // in our current buffer.
-  if (KnownOffsets.size() < Database.capacity())
-    KnownOffsets.resize(Database.capacity());
-  KnownOffsets[TI.toArrayIndex()] = Offset;
-  return Error::success();
-}

Added: llvm/trunk/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp?rev=303409&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp (added)
+++ llvm/trunk/lib/DebugInfo/CodeView/RandomAccessTypeVisitor.cpp Fri May 19 00:57:45 2017
@@ -0,0 +1,89 @@
+//===- RandomAccessTypeVisitor.cpp ---------------------------- *- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h"
+
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
+#include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+RandomAccessTypeVisitor::RandomAccessTypeVisitor(
+    const CVTypeArray &Types, uint32_t NumRecords,
+    PartialOffsetArray PartialOffsets)
+    : Database(NumRecords), Types(Types), DatabaseVisitor(Database),
+      PartialOffsets(PartialOffsets) {
+
+  KnownOffsets.resize(Database.capacity());
+}
+
+Error RandomAccessTypeVisitor::visitTypeIndex(TypeIndex TI,
+                                              TypeVisitorCallbacks &Callbacks) {
+  assert(TI.toArrayIndex() < Database.capacity());
+
+  if (!Database.contains(TI)) {
+    if (auto EC = visitRangeForType(TI))
+      return EC;
+  }
+
+  assert(Database.contains(TI));
+  auto &Record = Database.getTypeRecord(TI);
+  return codeview::visitTypeRecord(Record, TI, Callbacks);
+}
+
+Error RandomAccessTypeVisitor::visitRangeForType(TypeIndex TI) {
+  if (PartialOffsets.empty()) {
+    TypeIndex TIB(TypeIndex::FirstNonSimpleIndex);
+    TypeIndex TIE = TIB + Database.capacity();
+    return visitRange(TIB, 0, TIE);
+  }
+
+  auto Next = std::upper_bound(PartialOffsets.begin(), PartialOffsets.end(), TI,
+                               [](TypeIndex Value, const TypeIndexOffset &IO) {
+                                 return Value < IO.Type;
+                               });
+
+  assert(Next != PartialOffsets.begin());
+  auto Prev = std::prev(Next);
+
+  TypeIndex TIB = Prev->Type;
+  TypeIndex TIE;
+  if (Next == PartialOffsets.end()) {
+    TIE = TypeIndex::fromArrayIndex(Database.capacity());
+  } else {
+    TIE = Next->Type;
+  }
+
+  if (auto EC = visitRange(TIB, Prev->Offset, TIE))
+    return EC;
+  return Error::success();
+}
+
+Error RandomAccessTypeVisitor::visitRange(TypeIndex Begin, uint32_t BeginOffset,
+                                          TypeIndex End) {
+
+  auto RI = Types.at(BeginOffset);
+  assert(RI != Types.end());
+
+  while (Begin != End) {
+    assert(!Database.contains(Begin));
+    if (auto EC = codeview::visitTypeRecord(*RI, Begin, DatabaseVisitor))
+      return EC;
+    KnownOffsets[Begin.toArrayIndex()] = BeginOffset;
+
+    BeginOffset += RI.getRecordLength();
+    ++Begin;
+    ++RI;
+  }
+
+  return Error::success();
+}

Modified: llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/SymbolDumper.cpp Fri May 19 00:57:45 2017
@@ -11,6 +11,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
 #include "llvm/DebugInfo/CodeView/StringTable.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
@@ -32,9 +33,9 @@ namespace {
 /// the visitor out of SymbolDumper.h.
 class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
 public:
-  CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,
+  CVSymbolDumperImpl(TypeDatabase &TypeDB, SymbolDumpDelegate *ObjDelegate,
                      ScopedPrinter &W, bool PrintRecordBytes)
-      : Types(Types), ObjDelegate(ObjDelegate), W(W),
+      : TypeDB(TypeDB), ObjDelegate(ObjDelegate), W(W),
         PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
 
 /// CVSymbolVisitor overrides.
@@ -53,7 +54,7 @@ private:
   void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
   void printTypeIndex(StringRef FieldName, TypeIndex TI);
 
-  TypeCollection &Types;
+  TypeDatabase &TypeDB;
   SymbolDumpDelegate *ObjDelegate;
   ScopedPrinter &W;
 
@@ -82,7 +83,7 @@ void CVSymbolDumperImpl::printLocalVaria
 }
 
 void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
-  codeview::printTypeIndex(W, FieldName, TI, Types);
+  CVTypeDumper::printTypeIndex(W, FieldName, TI, TypeDB);
 }
 
 Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
@@ -669,7 +670,7 @@ Error CVSymbolDumperImpl::visitUnknownSy
 Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
   SymbolVisitorCallbackPipeline Pipeline;
   SymbolDeserializer Deserializer(ObjDelegate.get());
-  CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes);
+  CVSymbolDumperImpl Dumper(TypeDB, ObjDelegate.get(), W, PrintRecordBytes);
 
   Pipeline.addCallbackToPipeline(Deserializer);
   Pipeline.addCallbackToPipeline(Dumper);
@@ -680,7 +681,7 @@ Error CVSymbolDumper::dump(CVRecord<Symb
 Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
   SymbolVisitorCallbackPipeline Pipeline;
   SymbolDeserializer Deserializer(ObjDelegate.get());
-  CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, PrintRecordBytes);
+  CVSymbolDumperImpl Dumper(TypeDB, ObjDelegate.get(), W, PrintRecordBytes);
 
   Pipeline.addCallbackToPipeline(Deserializer);
   Pipeline.addCallbackToPipeline(Dumper);

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDatabase.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDatabase.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDatabase.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDatabase.cpp Fri May 19 00:57:45 2017
@@ -72,20 +72,16 @@ TypeDatabase::TypeDatabase(uint32_t Capa
 }
 
 TypeIndex TypeDatabase::appendType(StringRef Name, const CVType &Data) {
-  LargestTypeIndex = getAppendIndex();
-  if (LargestTypeIndex.toArrayIndex() >= capacity())
+  TypeIndex TI;
+  TI = getAppendIndex();
+  if (TI.toArrayIndex() >= capacity())
     grow();
-  recordType(Name, LargestTypeIndex, Data);
-  return LargestTypeIndex;
+  recordType(Name, TI, Data);
+  return TI;
 }
 
 void TypeDatabase::recordType(StringRef Name, TypeIndex Index,
                               const CVType &Data) {
-  LargestTypeIndex = empty() ? Index : std::max(Index, LargestTypeIndex);
-
-  if (LargestTypeIndex.toArrayIndex() >= capacity())
-    grow(Index);
-
   uint32_t AI = Index.toArrayIndex();
 
   assert(!contains(Index));
@@ -148,65 +144,19 @@ uint32_t TypeDatabase::size() const { re
 
 uint32_t TypeDatabase::capacity() const { return TypeRecords.size(); }
 
-CVType TypeDatabase::getType(TypeIndex Index) { return getTypeRecord(Index); }
-
-StringRef TypeDatabase::getTypeName(TypeIndex Index) {
-  return static_cast<const TypeDatabase *>(this)->getTypeName(Index);
-}
-
-bool TypeDatabase::contains(TypeIndex Index) {
-  return static_cast<const TypeDatabase *>(this)->contains(Index);
-}
-
-uint32_t TypeDatabase::size() {
-  return static_cast<const TypeDatabase *>(this)->size();
-}
-
-uint32_t TypeDatabase::capacity() {
-  return static_cast<const TypeDatabase *>(this)->capacity();
-}
-
-void TypeDatabase::grow() { grow(LargestTypeIndex + 1); }
-
-void TypeDatabase::grow(TypeIndex NewIndex) {
-  uint32_t NewSize = NewIndex.toArrayIndex() + 1;
-
-  if (NewSize <= capacity())
-    return;
-
-  uint32_t NewCapacity = NewSize * 3 / 2;
-
-  TypeRecords.resize(NewCapacity);
-  CVUDTNames.resize(NewCapacity);
-  ValidRecords.resize(NewCapacity);
+void TypeDatabase::grow() {
+  TypeRecords.emplace_back();
+  CVUDTNames.emplace_back();
+  ValidRecords.resize(ValidRecords.size() + 1);
 }
 
 bool TypeDatabase::empty() const { return size() == 0; }
 
-Optional<TypeIndex> TypeDatabase::largestTypeIndexLessThan(TypeIndex TI) const {
-  uint32_t AI = TI.toArrayIndex();
-  int N = ValidRecords.find_prev(AI);
-  if (N == -1)
-    return None;
-  return TypeIndex::fromArrayIndex(N);
-}
-
 TypeIndex TypeDatabase::getAppendIndex() const {
   if (empty())
     return TypeIndex::fromArrayIndex(0);
 
-  return LargestTypeIndex + 1;
-}
-
-TypeIndex TypeDatabase::getFirst() {
-  int N = ValidRecords.find_first();
-  assert(N != -1);
-  return TypeIndex::fromArrayIndex(N);
-}
-
-Optional<TypeIndex> TypeDatabase::getNext(TypeIndex Prev) {
-  int N = ValidRecords.find_next(Prev.toArrayIndex());
-  if (N == -1)
-    return None;
-  return TypeIndex::fromArrayIndex(N);
+  int Index = ValidRecords.find_last();
+  assert(Index != -1);
+  return TypeIndex::fromArrayIndex(Index) + 1;
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp Fri May 19 00:57:45 2017
@@ -10,13 +10,15 @@
 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
 
 #include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/Formatters.h"
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/Support/BinaryByteStream.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/ScopedPrinter.h"
@@ -163,15 +165,16 @@ static StringRef getLeafTypeName(TypeLea
 }
 
 void TypeDumpVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
-  codeview::printTypeIndex(*W, FieldName, TI, TpiTypes);
+  CVTypeDumper::printTypeIndex(*W, FieldName, TI, TypeDB);
 }
 
 void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
-  codeview::printTypeIndex(*W, FieldName, TI, getSourceTypes());
+  CVTypeDumper::printTypeIndex(*W, FieldName, TI, getSourceDB());
 }
 
 Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
-  return visitTypeBegin(Record, TypeIndex::fromArrayIndex(TpiTypes.size()));
+  TypeIndex TI = getSourceDB().getAppendIndex();
+  return visitTypeBegin(Record, TI);
 }
 
 Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
@@ -242,7 +245,7 @@ Error TypeDumpVisitor::visitKnownRecord(
   W->printNumber("NumStrings", Size);
   ListScope Arguments(*W, "Strings");
   for (uint32_t I = 0; I < Size; ++I) {
-    printItemIndex("String", Indices[I]);
+    printTypeIndex("String", Indices[I]);
   }
   return Error::success();
 }

Removed: llvm/trunk/lib/DebugInfo/CodeView/TypeIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeIndex.cpp?rev=303408&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeIndex.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeIndex.cpp (removed)
@@ -1,27 +0,0 @@
-//===-- TypeIndex.cpp - CodeView type index ---------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
-                                    TypeIndex TI, TypeCollection &Types) {
-  StringRef TypeName;
-  if (!TI.isNoneType())
-    TypeName = Types.getTypeName(TI);
-  if (!TypeName.empty())
-    Printer.printHex(FieldName, TypeName, TI.getIndex());
-  else
-    Printer.printHex(FieldName, TI.getIndex());
-}

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Fri May 19 00:57:45 2017
@@ -11,9 +11,11 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ScopedPrinter.h"

Removed: llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp?rev=303408&view=auto
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeTableCollection.cpp (removed)
@@ -1,82 +0,0 @@
-//===- TypeTableCollection.cpp -------------------------------- *- C++ --*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamReader.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static void error(Error &&EC) {
-  assert(!static_cast<bool>(EC));
-  if (EC)
-    consumeError(std::move(EC));
-}
-
-TypeTableCollection::TypeTableCollection(
-    ArrayRef<MutableArrayRef<uint8_t>> Records)
-    : Records(Records), Database(Records.size()) {}
-
-TypeIndex TypeTableCollection::getFirst() {
-  assert(!empty());
-  return TypeIndex::fromArrayIndex(0);
-}
-
-Optional<TypeIndex> TypeTableCollection::getNext(TypeIndex Prev) {
-  ++Prev;
-  assert(Prev.toArrayIndex() <= size());
-  if (Prev.toArrayIndex() == size())
-    return None;
-  return Prev;
-}
-
-void TypeTableCollection::ensureTypeExists(TypeIndex Index) {
-  assert(hasCapacityFor(Index));
-
-  if (Database.contains(Index))
-    return;
-
-  BinaryByteStream Bytes(Records[Index.toArrayIndex()], support::little);
-
-  CVType Type;
-  uint32_t Len;
-  error(VarStreamArrayExtractor<CVType>::extract(Bytes, Len, Type));
-
-  TypeDatabaseVisitor DBV(Database);
-  error(codeview::visitTypeRecord(Type, Index, DBV));
-  assert(Database.contains(Index));
-}
-
-CVType TypeTableCollection::getType(TypeIndex Index) {
-  ensureTypeExists(Index);
-  return Database.getTypeRecord(Index);
-}
-
-StringRef TypeTableCollection::getTypeName(TypeIndex Index) {
-  if (!Index.isSimple())
-    ensureTypeExists(Index);
-  return Database.getTypeName(Index);
-}
-
-bool TypeTableCollection::contains(TypeIndex Index) {
-  return Database.contains(Index);
-}
-
-uint32_t TypeTableCollection::size() { return Records.size(); }
-
-uint32_t TypeTableCollection::capacity() { return Records.size(); }
-
-bool TypeTableCollection::hasCapacityFor(TypeIndex Index) const {
-  return Index.toArrayIndex() < Records.size();
-}

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBTypeServerHandler.cpp Fri May 19 00:57:45 2017
@@ -21,7 +21,6 @@
 
 #include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h"
 
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
 #include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/TpiStream.cpp Fri May 19 00:57:45 2017
@@ -9,7 +9,10 @@
 
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h"

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Fri May 19 00:57:45 2017
@@ -326,7 +326,7 @@
 ; EMPTY-NEXT:           TypeLeafKind: LF_SUBSTR_LIST (0x1604)
 ; EMPTY-NEXT:           NumStrings: 1
 ; EMPTY-NEXT:           Strings [
-; EMPTY-NEXT:             String: -Zi -MT -I"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared" -I"C:\Program Files (x86)\Windows
+; EMPTY-NEXT:             String: __vc_attributes::threadingAttribute (0x100B)
 ; EMPTY-NEXT:           ]
 ; EMPTY-NEXT:         }
 ; EMPTY-NEXT:         Bytes (
@@ -1253,7 +1253,7 @@
 ; ALL:         TypeLeafKind: LF_SUBSTR_LIST (0x1604)
 ; ALL:         NumStrings: 1
 ; ALL:         Strings [
-; ALL:           String: -Zi -MT -I"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared" -I"C:\Program Files (x86)\Windows (0x100B)
+; ALL:           String: __vc_attributes::threadingAttribute (0x100B)
 ; ALL:         ]
 ; ALL:       }
 ; ALL:     }

Modified: llvm/trunk/tools/llvm-pdbdump/Analyze.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/Analyze.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/Analyze.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/Analyze.cpp Fri May 19 00:57:45 2017
@@ -14,6 +14,7 @@
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabase.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"

Modified: llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp Fri May 19 00:57:45 2017
@@ -29,15 +29,15 @@ static StringRef getLeafName(TypeLeafKin
   return StringRef();
 }
 
-CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types,
+CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB,
                                                ScopedPrinter *W)
-    : CompactTypeDumpVisitor(Types, TypeIndex(TypeIndex::FirstNonSimpleIndex),
+    : CompactTypeDumpVisitor(TypeDB, TypeIndex(TypeIndex::FirstNonSimpleIndex),
                              W) {}
 
-CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types,
+CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB,
                                                TypeIndex FirstTI,
                                                ScopedPrinter *W)
-    : W(W), TI(FirstTI), Offset(0), Types(Types) {}
+    : W(W), TI(FirstTI), Offset(0), TypeDB(TypeDB) {}
 
 Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) {
   return Error::success();
@@ -46,7 +46,7 @@ Error CompactTypeDumpVisitor::visitTypeB
 Error CompactTypeDumpVisitor::visitTypeEnd(CVType &Record) {
   uint32_t I = TI.getIndex();
   StringRef Leaf = getLeafName(Record.Type);
-  StringRef Name = Types.getTypeName(TI);
+  StringRef Name = TypeDB.getTypeName(TI);
   W->printString(
       llvm::formatv("Index: {0:x} ({1:N} bytes, offset {2:N}) {3} \"{4}\"", I,
                     Record.length(), Offset, Leaf, Name)

Modified: llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/CompactTypeDumpVisitor.h Fri May 19 00:57:45 2017
@@ -17,7 +17,7 @@
 namespace llvm {
 class ScopedPrinter;
 namespace codeview {
-class TypeCollection;
+class TypeDatabase;
 }
 
 namespace pdb {
@@ -26,8 +26,8 @@ namespace pdb {
 /// Dumps records on a single line, and ignores member records.
 class CompactTypeDumpVisitor : public codeview::TypeVisitorCallbacks {
 public:
-  CompactTypeDumpVisitor(codeview::TypeCollection &Types, ScopedPrinter *W);
-  CompactTypeDumpVisitor(codeview::TypeCollection &Types,
+  CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB, ScopedPrinter *W);
+  CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB,
                          codeview::TypeIndex FirstTI, ScopedPrinter *W);
 
   /// Paired begin/end actions for all types. Receives all record data,
@@ -40,7 +40,7 @@ private:
 
   codeview::TypeIndex TI;
   uint32_t Offset;
-  codeview::TypeCollection &Types;
+  codeview::TypeDatabase &TypeDB;
 };
 
 } // end namespace pdb

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Fri May 19 00:57:45 2017
@@ -14,9 +14,9 @@
 #include "StreamUtil.h"
 #include "llvm-pdbdump.h"
 
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
@@ -25,6 +25,7 @@
 #include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -83,7 +84,7 @@ struct PageStats {
 
 class C13RawVisitor : public C13DebugFragmentVisitor {
 public:
-  C13RawVisitor(ScopedPrinter &P, PDBFile &F, LazyRandomTypeCollection &IPI)
+  C13RawVisitor(ScopedPrinter &P, PDBFile &F, TypeDatabase &IPI)
       : C13DebugFragmentVisitor(F), P(P), IPI(IPI) {}
 
   Error handleLines() override {
@@ -159,7 +160,7 @@ public:
         if (auto EC = printFileName("FileName", L.Header->FileID))
           return EC;
 
-        if (auto EC = dumpTypeRecord("Function", L.Header->Inlinee))
+        if (auto EC = dumpTypeRecord("Function", IPI, L.Header->Inlinee))
           return EC;
         P.printNumber("SourceLine", L.Header->SourceLineNum);
         if (IL.hasExtraFiles()) {
@@ -175,11 +176,11 @@ public:
   }
 
 private:
-  Error dumpTypeRecord(StringRef Label, TypeIndex Index) {
-    CompactTypeDumpVisitor CTDV(IPI, Index, &P);
+  Error dumpTypeRecord(StringRef Label, TypeDatabase &DB, TypeIndex Index) {
+    CompactTypeDumpVisitor CTDV(DB, Index, &P);
     DictScope D(P, Label);
-    if (IPI.contains(Index)) {
-      CVType Type = IPI.getType(Index);
+    if (DB.contains(Index)) {
+      CVType &Type = DB.getTypeRecord(Index);
       if (auto EC = codeview::visitTypeRecord(Type, CTDV))
         return EC;
     } else {
@@ -198,7 +199,7 @@ private:
   }
 
   ScopedPrinter &P;
-  LazyRandomTypeCollection &IPI;
+  TypeDatabase &IPI;
 };
 }
 
@@ -608,19 +609,14 @@ Error LLVMOutputStyle::dumpTpiStream(uin
     VerLabel = "IPI Version";
   }
 
+  if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
+    return Error::success();
+
   auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
                                       : File.getPDBIpiStream();
   if (!Tpi)
     return Tpi.takeError();
 
-  auto ExpectedTypes = initializeTypeDatabase(StreamIdx);
-  if (!ExpectedTypes)
-    return ExpectedTypes.takeError();
-  auto &Types = *ExpectedTypes;
-
-  if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
-    return Error::success();
-
   std::unique_ptr<DictScope> StreamScope;
   std::unique_ptr<ListScope> RecordScope;
 
@@ -628,19 +624,25 @@ Error LLVMOutputStyle::dumpTpiStream(uin
   P.printNumber(VerLabel, Tpi->getTpiVersion());
   P.printNumber("Record count", Tpi->getNumTypeRecords());
 
+  Optional<TypeDatabase> &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB;
+
   std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors;
 
+  if (!StreamDB.hasValue()) {
+    StreamDB.emplace(Tpi->getNumTypeRecords());
+    Visitors.push_back(make_unique<TypeDatabaseVisitor>(*StreamDB));
+  }
   // If we're in dump mode, add a dumper with the appropriate detail level.
   if (DumpRecords) {
     std::unique_ptr<TypeVisitorCallbacks> Dumper;
     if (opts::raw::CompactRecords)
-      Dumper = make_unique<CompactTypeDumpVisitor>(Types, &P);
+      Dumper = make_unique<CompactTypeDumpVisitor>(*StreamDB, &P);
     else {
-      assert(TpiTypes);
+      assert(TypeDB.hasValue());
 
-      auto X = make_unique<TypeDumpVisitor>(*TpiTypes, &P, false);
+      auto X = make_unique<TypeDumpVisitor>(*TypeDB, &P, false);
       if (StreamIdx == StreamIPI)
-        X->setIpiTypes(*IpiTypes);
+        X->setItemDB(*ItemDB);
       Dumper = std::move(X);
     }
     Visitors.push_back(std::move(Dumper));
@@ -658,17 +660,23 @@ Error LLVMOutputStyle::dumpTpiStream(uin
   if (DumpRecords || DumpRecordBytes)
     RecordScope = llvm::make_unique<ListScope>(P, "Records");
 
-  Optional<TypeIndex> I = Types.getFirst();
-  do {
+  bool HadError = false;
+
+  TypeIndex T(TypeIndex::FirstNonSimpleIndex);
+  for (auto Type : Tpi->types(&HadError)) {
     std::unique_ptr<DictScope> OneRecordScope;
 
     if ((DumpRecords || DumpRecordBytes) && !opts::raw::CompactRecords)
       OneRecordScope = llvm::make_unique<DictScope>(P, "");
 
-    auto T = Types.getType(*I);
-    if (auto EC = codeview::visitTypeRecord(T, *I, Pipeline))
+    if (auto EC = codeview::visitTypeRecord(Type, Pipeline))
       return EC;
-  } while ((I = Types.getNext(*I)));
+
+    ++T;
+  }
+  if (HadError)
+    return make_error<RawError>(raw_error_code::corrupt_file,
+                                "TPI stream contained corrupt record");
 
   if (DumpTpiHash) {
     DictScope DD(P, "Hash");
@@ -703,26 +711,35 @@ Error LLVMOutputStyle::dumpTpiStream(uin
   return Error::success();
 }
 
-Expected<codeview::LazyRandomTypeCollection &>
-LLVMOutputStyle::initializeTypeDatabase(uint32_t SN) {
-  auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes;
+Error LLVMOutputStyle::buildTypeDatabase(uint32_t SN) {
+  assert(SN == StreamIPI || SN == StreamTPI);
+
+  auto &DB = (SN == StreamIPI) ? ItemDB : TypeDB;
+
+  if (DB.hasValue())
+    return Error::success();
+
   auto Tpi =
       (SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream();
+
   if (!Tpi)
     return Tpi.takeError();
 
-  if (!TypeCollection) {
-    // Initialize the type collection, even if we're not going to dump it.  This
-    // way if some other part of the dumper decides it wants to use some or all
-    // of the records for whatever purposes, it can still access them lazily.
-    auto &Types = Tpi->typeArray();
-    uint32_t Count = Tpi->getNumTypeRecords();
-    auto Offsets = Tpi->getTypeIndexOffsets();
-    TypeCollection =
-        llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
-  }
+  DB.emplace(Tpi->getNumTypeRecords());
+
+  TypeDatabaseVisitor DBV(*DB);
+
+  auto HashValues = Tpi->getHashValues();
+  if (HashValues.empty())
+    return codeview::visitTypeStream(Tpi->typeArray(), DBV);
 
-  return *TypeCollection;
+  TypeVisitorCallbackPipeline Pipeline;
+  Pipeline.addCallbackToPipeline(DBV);
+
+  TpiHashVerifier HashVerifier(HashValues, Tpi->getNumHashBuckets());
+  Pipeline.addCallbackToPipeline(HashVerifier);
+
+  return codeview::visitTypeStream(Tpi->typeArray(), Pipeline);
 }
 
 Error LLVMOutputStyle::dumpDbiStream() {
@@ -797,13 +814,11 @@ Error LLVMOutputStyle::dumpDbiStream() {
           return EC;
 
         if (ShouldDumpSymbols) {
-          auto ExpectedTypes = initializeTypeDatabase(StreamTPI);
-          if (!ExpectedTypes)
-            return ExpectedTypes.takeError();
-          auto &Types = *ExpectedTypes;
+          if (auto EC = buildTypeDatabase(StreamTPI))
+            return EC;
 
           ListScope SS(P, "Symbols");
-          codeview::CVSymbolDumper SD(P, Types, nullptr, false);
+          codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
           bool HadError = false;
           for (auto S : ModS.symbols(&HadError)) {
             DictScope LL(P, "");
@@ -824,11 +839,10 @@ Error LLVMOutputStyle::dumpDbiStream() {
         }
         if (opts::raw::DumpLineInfo) {
           ListScope SS(P, "LineInfo");
-          auto ExpectedTypes = initializeTypeDatabase(StreamIPI);
-          if (!ExpectedTypes)
-            return ExpectedTypes.takeError();
-          auto &IpiItems = *ExpectedTypes;
-          C13RawVisitor V(P, File, IpiItems);
+          if (auto EC = buildTypeDatabase(StreamIPI))
+            return EC;
+
+          C13RawVisitor V(P, File, *ItemDB);
           if (auto EC = codeview::visitModuleDebugFragments(
                   ModS.linesAndChecksums(), V))
             return EC;
@@ -946,12 +960,10 @@ Error LLVMOutputStyle::dumpPublicsStream
   P.printList("Section Offsets", Publics->getSectionOffsets(),
               printSectionOffset);
   ListScope L(P, "Symbols");
-  auto ExpectedTypes = initializeTypeDatabase(StreamTPI);
-  if (!ExpectedTypes)
-    return ExpectedTypes.takeError();
-  auto &Tpi = *ExpectedTypes;
+  if (auto EC = buildTypeDatabase(StreamTPI))
+    return EC;
 
-  codeview::CVSymbolDumper SD(P, Tpi, nullptr, false);
+  codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
   bool HadError = false;
   for (auto S : Publics->getSymbols(&HadError)) {
     DictScope DD(P, "");

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.h Fri May 19 00:57:45 2017
@@ -21,11 +21,6 @@
 
 namespace llvm {
 class BitVector;
-
-namespace codeview {
-class LazyRandomTypeCollection;
-}
-
 namespace pdb {
 class LLVMOutputStyle : public OutputStyle {
 public:
@@ -34,8 +29,7 @@ public:
   Error dump() override;
 
 private:
-  Expected<codeview::LazyRandomTypeCollection &>
-  initializeTypeDatabase(uint32_t SN);
+  Error buildTypeDatabase(uint32_t SN);
 
   Error dumpFileHeaders();
   Error dumpStreamSummary();
@@ -60,8 +54,8 @@ private:
 
   PDBFile &File;
   ScopedPrinter P;
-  std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes;
-  std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes;
+  Optional<codeview::TypeDatabase> TypeDB;
+  Optional<codeview::TypeDatabase> ItemDB;
   SmallVector<std::string, 32> StreamPurposes;
 };
 }

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp Fri May 19 00:57:45 2017
@@ -19,6 +19,7 @@
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -370,6 +371,7 @@ void MappingContextTraits<PdbInlineeInfo
 void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
     mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
             pdb::yaml::SerializationContext &Context) {
+
   if (IO.outputting()) {
     // For PDB to Yaml, deserialize into a high level record type, then dump it.
     consumeError(codeview::visitTypeRecord(Obj.Record, Context.Dumper));

Modified: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h Fri May 19 00:57:45 2017
@@ -13,6 +13,7 @@
 #include "OutputStyle.h"
 #include "PdbYaml.h"
 
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/YAMLTraits.h"
 

Modified: llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YamlTypeDumper.cpp Fri May 19 00:57:45 2017
@@ -13,6 +13,7 @@
 
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri May 19 00:57:45 2017
@@ -31,7 +31,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Config/config.h"
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
@@ -886,7 +885,7 @@ static void mergePdbs() {
         DestIpi.addTypeRecord(Data, None);
       });
 
-  SmallString<64> OutFile(opts::merge::PdbOutputFile);
+  SmallString<64> OutFile = opts::merge::PdbOutputFile;
   if (OutFile.empty()) {
     OutFile = opts::merge::InputFilenames[0];
     llvm::sys::path::replace_extension(OutFile, "merged.pdb");

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Fri May 19 00:57:45 2017
@@ -22,9 +22,8 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
@@ -35,13 +34,11 @@
 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
-#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/BinaryStreamReader.h"
@@ -73,7 +70,7 @@ class COFFDumper : public ObjDumper {
 public:
   friend class COFFObjectDumpDelegate;
   COFFDumper(const llvm::object::COFFObjectFile *Obj, ScopedPrinter &Writer)
-      : ObjDumper(Writer), Obj(Obj), Writer(Writer), Types(100) {}
+      : ObjDumper(Writer), Obj(Obj), Writer(Writer), TypeDB(100) {}
 
   void printFileHeaders() override;
   void printSections() override;
@@ -109,7 +106,7 @@ private:
   void printFileNameForOffset(StringRef Label, uint32_t FileOffset);
   void printTypeIndex(StringRef FieldName, TypeIndex TI) {
     // Forward to CVTypeDumper for simplicity.
-    codeview::printTypeIndex(Writer, FieldName, TI, Types);
+    CVTypeDumper::printTypeIndex(Writer, FieldName, TI, TypeDB);
   }
 
   void printCodeViewSymbolsSubsection(StringRef Subsection,
@@ -162,8 +159,7 @@ private:
   StringTableRef CVStringTable;
 
   ScopedPrinter &Writer;
-  BinaryByteStream TypeContents;
-  LazyRandomTypeCollection Types;
+  TypeDatabase TypeDB;
 };
 
 class COFFObjectDumpDelegate : public SymbolDumpDelegate {
@@ -979,7 +975,9 @@ void COFFDumper::printCodeViewSymbolsSub
                                Subsection.bytes_end());
   auto CODD = llvm::make_unique<COFFObjectDumpDelegate>(*this, Section, Obj,
                                                         SectionContents);
-  CVSymbolDumper CVSD(W, Types, std::move(CODD), opts::CodeViewSubsectionBytes);
+
+  CVSymbolDumper CVSD(W, TypeDB, std::move(CODD),
+                      opts::CodeViewSubsectionBytes);
   CVSymbolArray Symbols;
   BinaryStreamReader Reader(BinaryData, llvm::support::little);
   if (auto EC = Reader.readArray(Symbols, Reader.getLength())) {
@@ -1096,11 +1094,12 @@ void COFFDumper::printCodeViewTypeSectio
   if (Magic != COFF::DEBUG_SECTION_MAGIC)
     return error(object_error::parse_failed);
 
-  Types.reset(Data);
-
-  TypeDumpVisitor TDV(Types, &W, opts::CodeViewSubsectionBytes);
-  error(codeview::visitTypeStream(Types, TDV));
-  W.flush();
+  CVTypeDumper CVTD(TypeDB);
+  TypeDumpVisitor TDV(TypeDB, &W, opts::CodeViewSubsectionBytes);
+  if (auto EC = CVTD.dump({Data.bytes_begin(), Data.bytes_end()}, TDV)) {
+    W.flush();
+    error(llvm::errorToErrorCode(std::move(EC)));
+  }
 }
 
 void COFFDumper::printSections() {
@@ -1640,22 +1639,35 @@ void llvm::dumpCodeViewMergedTypes(Scope
     TypeBuf.append(Record.begin(), Record.end());
   });
 
-  TypeTableCollection TpiTypes(CVTypes.records());
+  TypeDatabase TypeDB(CVTypes.records().size());
   {
     ListScope S(Writer, "MergedTypeStream");
-    TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
-    error(codeview::visitTypeStream(TpiTypes, TDV));
-    Writer.flush();
+    CVTypeDumper CVTD(TypeDB);
+    TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes);
+    if (auto EC = CVTD.dump(
+            {TypeBuf.str().bytes_begin(), TypeBuf.str().bytes_end()}, TDV)) {
+      Writer.flush();
+      error(std::move(EC));
+    }
   }
 
   // Flatten the id stream and print it next. The ID stream refers to names from
   // the type stream.
-  TypeTableCollection IpiTypes(IDTable.records());
+  SmallString<0> IDBuf;
+  IDTable.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Record) {
+    IDBuf.append(Record.begin(), Record.end());
+  });
+
   {
     ListScope S(Writer, "MergedIDStream");
-    TypeDumpVisitor TDV(TpiTypes, &Writer, opts::CodeViewSubsectionBytes);
-    TDV.setIpiTypes(IpiTypes);
-    error(codeview::visitTypeStream(IpiTypes, TDV));
-    Writer.flush();
+    TypeDatabase IDDB(IDTable.records().size());
+    CVTypeDumper CVTD(IDDB);
+    TypeDumpVisitor TDV(TypeDB, &Writer, opts::CodeViewSubsectionBytes);
+    TDV.setItemDB(IDDB);
+    if (auto EC = CVTD.dump(
+            {IDBuf.str().bytes_begin(), IDBuf.str().bytes_end()}, TDV)) {
+      Writer.flush();
+      error(std::move(EC));
+    }
   }
 }

Modified: llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp?rev=303409&r1=303408&r2=303409&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/CodeView/RandomAccessVisitorTest.cpp Fri May 19 00:57:45 2017
@@ -11,12 +11,14 @@
 
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/RandomAccessTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
 #include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
 #include "llvm/DebugInfo/CodeView/TypeServerHandler.h"
 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
 #include "llvm/Support/Allocator.h"
@@ -128,16 +130,20 @@ public:
 
   void SetUp() override {
     TestState = llvm::make_unique<PerTestState>();
+
+    TestState->Pipeline.addCallbackToPipeline(TestState->Deserializer);
+    TestState->Pipeline.addCallbackToPipeline(TestState->Callbacks);
   }
 
   void TearDown() override { TestState.reset(); }
 
 protected:
-  bool ValidateDatabaseRecord(LazyRandomTypeCollection &Types, uint32_t Index) {
+  bool ValidateDatabaseRecord(const RandomAccessTypeVisitor &Visitor,
+                              uint32_t Index) {
     TypeIndex TI = TypeIndex::fromArrayIndex(Index);
-    if (!Types.contains(TI))
+    if (!Visitor.database().contains(TI))
       return false;
-    if (GlobalState->TypeVector[Index] != Types.getType(TI))
+    if (GlobalState->TypeVector[Index] != Visitor.database().getTypeRecord(TI))
       return false;
     return true;
   }
@@ -178,6 +184,8 @@ protected:
   struct PerTestState {
     FixedStreamArray<TypeIndexOffset> Offsets;
 
+    TypeVisitorCallbackPipeline Pipeline;
+    TypeDeserializer Deserializer;
     MockCallbacks Callbacks;
   };
 
@@ -210,22 +218,21 @@ std::unique_ptr<RandomAccessVisitorTest:
 
 TEST_F(RandomAccessVisitorTest, MultipleVisits) {
   TestState->Offsets = createPartialOffsets(GlobalState->Stream, {0, 8});
-  LazyRandomTypeCollection Types(GlobalState->TypeArray,
-                                 GlobalState->TypeVector.size(),
-                                 TestState->Offsets);
+  RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+                                  GlobalState->TypeVector.size(),
+                                  TestState->Offsets);
 
   std::vector<uint32_t> IndicesToVisit = {5, 5, 5};
 
   for (uint32_t I : IndicesToVisit) {
     TypeIndex TI = TypeIndex::fromArrayIndex(I);
-    CVType T = Types.getType(TI);
-    EXPECT_NO_ERROR(codeview::visitTypeRecord(T, TI, TestState->Callbacks));
+    EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
   }
 
   // [0,8) should be present
-  EXPECT_EQ(8u, Types.size());
+  EXPECT_EQ(8u, Visitor.database().size());
   for (uint32_t I = 0; I < 8; ++I)
-    EXPECT_TRUE(ValidateDatabaseRecord(Types, I));
+    EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
 
   // 5, 5, 5
   EXPECT_EQ(3u, TestState->Callbacks.count());
@@ -241,19 +248,19 @@ TEST_F(RandomAccessVisitorTest, Descendi
 
   std::vector<uint32_t> IndicesToVisit = {7, 4, 2};
 
-  LazyRandomTypeCollection Types(GlobalState->TypeArray,
-                                 GlobalState->TypeVector.size(),
-                                 TestState->Offsets);
+  RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+                                  GlobalState->TypeVector.size(),
+                                  TestState->Offsets);
+
   for (uint32_t I : IndicesToVisit) {
     TypeIndex TI = TypeIndex::fromArrayIndex(I);
-    CVType T = Types.getType(TI);
-    EXPECT_NO_ERROR(codeview::visitTypeRecord(T, TI, TestState->Callbacks));
+    EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
   }
 
   // [0, 7]
-  EXPECT_EQ(8u, Types.size());
+  EXPECT_EQ(8u, Visitor.database().size());
   for (uint32_t I = 0; I < 8; ++I)
-    EXPECT_TRUE(ValidateDatabaseRecord(Types, I));
+    EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
 
   // 2, 4, 7
   EXPECT_EQ(3u, TestState->Callbacks.count());
@@ -269,19 +276,19 @@ TEST_F(RandomAccessVisitorTest, Ascendin
 
   std::vector<uint32_t> IndicesToVisit = {2, 4, 7};
 
-  LazyRandomTypeCollection Types(GlobalState->TypeArray,
-                                 GlobalState->TypeVector.size(),
-                                 TestState->Offsets);
+  RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+                                  GlobalState->TypeVector.size(),
+                                  TestState->Offsets);
+
   for (uint32_t I : IndicesToVisit) {
     TypeIndex TI = TypeIndex::fromArrayIndex(I);
-    CVType T = Types.getType(TI);
-    EXPECT_NO_ERROR(codeview::visitTypeRecord(T, TI, TestState->Callbacks));
+    EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
   }
 
   // [0, 7]
-  EXPECT_EQ(8u, Types.size());
+  EXPECT_EQ(8u, Visitor.database().size());
   for (uint32_t I = 0; I < 8; ++I)
-    EXPECT_TRUE(ValidateDatabaseRecord(Types, I));
+    EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
 
   // 2, 4, 7
   EXPECT_EQ(3u, TestState->Callbacks.count());
@@ -298,20 +305,19 @@ TEST_F(RandomAccessVisitorTest, StopPrem
 
   std::vector<uint32_t> IndicesToVisit = {0, 1, 2};
 
-  LazyRandomTypeCollection Types(GlobalState->TypeArray,
-                                 GlobalState->TypeVector.size(),
-                                 TestState->Offsets);
+  RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+                                  GlobalState->TypeVector.size(),
+                                  TestState->Offsets);
 
   for (uint32_t I : IndicesToVisit) {
     TypeIndex TI = TypeIndex::fromArrayIndex(I);
-    CVType T = Types.getType(TI);
-    EXPECT_NO_ERROR(codeview::visitTypeRecord(T, TI, TestState->Callbacks));
+    EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
   }
 
   // [0, 8) should be visited.
-  EXPECT_EQ(8u, Types.size());
+  EXPECT_EQ(8u, Visitor.database().size());
   for (uint32_t I = 0; I < 8; ++I)
-    EXPECT_TRUE(ValidateDatabaseRecord(Types, I));
+    EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
 
   // [0, 2]
   EXPECT_EQ(3u, TestState->Callbacks.count());
@@ -327,20 +333,19 @@ TEST_F(RandomAccessVisitorTest, InnerChu
 
   std::vector<uint32_t> IndicesToVisit = {5, 7};
 
-  LazyRandomTypeCollection Types(GlobalState->TypeArray,
-                                 GlobalState->TypeVector.size(),
-                                 TestState->Offsets);
+  RandomAccessTypeVisitor Visitor(GlobalState->TypeArray,
+                                  GlobalState->TypeVector.size(),
+                                  TestState->Offsets);
 
   for (uint32_t I : IndicesToVisit) {
     TypeIndex TI = TypeIndex::fromArrayIndex(I);
-    CVType T = Types.getType(TI);
-    EXPECT_NO_ERROR(codeview::visitTypeRecord(T, TI, TestState->Callbacks));
+    EXPECT_NO_ERROR(Visitor.visitTypeIndex(TI, TestState->Pipeline));
   }
 
   // [4, 9)
-  EXPECT_EQ(5u, Types.size());
+  EXPECT_EQ(5u, Visitor.database().size());
   for (uint32_t I = 4; I < 9; ++I)
-    EXPECT_TRUE(ValidateDatabaseRecord(Types, I));
+    EXPECT_TRUE(ValidateDatabaseRecord(Visitor, I));
 
   // 5, 7
   EXPECT_EQ(2u, TestState->Callbacks.count());




More information about the llvm-commits mailing list