Index: llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
@@ -141,13 +141,6 @@
   //   ulittle32_t Files[];
 };
 
-struct FileChecksum {
-  ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
-  uint8_t ChecksumSize;       // Number of bytes of checksum.
-  uint8_t ChecksumKind;       // FileChecksumKind
-  // Checksum bytes follow.
-};
-
 } // namespace codeview
 } // namespace llvm
 
Index: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
@@ -0,0 +1,65 @@
+//===- ModuleDebugLineFragment.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_MODULEDEBUGFILECHECKSUMFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace codeview {
+
+struct FileChecksumEntry {
+  uint32_t FileNameOffset;    // Byte offset of filename in global stringtable.
+  FileChecksumKind Kind;      // The type of checksum.
+  ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
+};
+}
+}
+
+namespace llvm {
+template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> {
+public:
+  typedef void ContextType;
+
+  static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+                       codeview::FileChecksumEntry &Item, void *Ctx);
+};
+}
+
+namespace llvm {
+namespace codeview {
+class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment {
+  typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
+  typedef FileChecksumArray::Iterator Iterator;
+
+public:
+  ModuleDebugFileChecksumFragment()
+      : ModuleDebugFragment(ModuleDebugFragmentKind::FileChecksums) {}
+
+  static bool classof(const ModuleDebugFragment *S) {
+    return S->kind() == ModuleDebugFragmentKind::FileChecksums;
+  }
+
+  Error initialize(BinaryStreamReader Reader);
+
+  Iterator begin() const { return Checksums.begin(); }
+  Iterator end() const { return Checksums.end(); }
+
+private:
+  FileChecksumArray Checksums;
+};
+}
+}
+
+#endif
Index: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
@@ -11,79 +11,23 @@
 #define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
 
 #include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/BinaryStreamArray.h"
-#include "llvm/Support/BinaryStreamRef.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
+#include "llvm/Support/Casting.h"
 
 namespace llvm {
 namespace codeview {
 
-// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
-struct ModuleDebugFragmentHeader {
-  support::ulittle32_t Kind;   // codeview::ModuleDebugFragmentKind enum
-  support::ulittle32_t Length; // number of bytes occupied by this record.
-};
-
-// Corresponds to the `CV_DebugSLinesHeader_t` structure.
-struct LineFragmentHeader {
-  support::ulittle32_t RelocOffset;  // Code offset of line contribution.
-  support::ulittle16_t RelocSegment; // Code segment of line contribution.
-  support::ulittle16_t Flags;        // See LineFlags enumeration.
-  support::ulittle32_t CodeSize;     // Code size of this line contribution.
-};
-
-// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
-struct LineBlockFragmentHeader {
-  support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
-  support::ulittle32_t NumLines;  // Number of lines
-  support::ulittle32_t BlockSize; // Code size of block, in bytes.
-  // The following two variable length arrays appear immediately after the
-  // header.  The structure definitions follow.
-  // LineNumberEntry   Lines[NumLines];
-  // ColumnNumberEntry Columns[NumLines];
-};
-
-// Corresponds to `CV_Line_t` structure
-struct LineNumberEntry {
-  support::ulittle32_t Offset; // Offset to start of code bytes for line number
-  support::ulittle32_t Flags;  // Start:24, End:7, IsStatement:1
-};
-
-// Corresponds to `CV_Column_t` structure
-struct ColumnNumberEntry {
-  support::ulittle16_t StartColumn;
-  support::ulittle16_t EndColumn;
-};
-
 class ModuleDebugFragment {
 public:
-  ModuleDebugFragment();
-  ModuleDebugFragment(ModuleDebugFragmentKind Kind, BinaryStreamRef Data);
-  static Error initialize(BinaryStreamRef Stream, ModuleDebugFragment &Info);
-  uint32_t getRecordLength() const;
-  ModuleDebugFragmentKind kind() const;
-  BinaryStreamRef getRecordData() const;
+  explicit ModuleDebugFragment(ModuleDebugFragmentKind Kind) : Kind(Kind) {}
+
+  virtual ~ModuleDebugFragment();
+  ModuleDebugFragmentKind kind() const { return Kind; }
 
-private:
+protected:
   ModuleDebugFragmentKind Kind;
-  BinaryStreamRef Data;
 };
 
-typedef VarStreamArray<ModuleDebugFragment> ModuleDebugFragmentArray;
 } // namespace codeview
-
-template <> struct VarStreamArrayExtractor<codeview::ModuleDebugFragment> {
-  typedef void ContextType;
-
-  static Error extract(BinaryStreamRef Stream, uint32_t &Length,
-                       codeview::ModuleDebugFragment &Info, void *Ctx) {
-    if (auto EC = codeview::ModuleDebugFragment::initialize(Stream, Info))
-      return EC;
-    Length = Info.getRecordLength();
-    return Error::success();
-  }
-};
 } // namespace llvm
 
 #endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H
Index: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
@@ -0,0 +1,62 @@
+//===- ModuleDebugFragment.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_MODULEDEBUGFRAGMENTRECORD_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+// Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
+struct ModuleDebugFragmentHeader {
+  support::ulittle32_t Kind;   // codeview::ModuleDebugFragmentKind enum
+  support::ulittle32_t Length; // number of bytes occupied by this record.
+};
+
+class ModuleDebugFragmentRecord {
+public:
+  ModuleDebugFragmentRecord();
+  ModuleDebugFragmentRecord(ModuleDebugFragmentKind Kind, BinaryStreamRef Data);
+
+  static Error initialize(BinaryStreamRef Stream,
+                          ModuleDebugFragmentRecord &Info);
+  uint32_t getRecordLength() const;
+  ModuleDebugFragmentKind kind() const;
+  BinaryStreamRef getRecordData() const;
+
+private:
+  ModuleDebugFragmentKind Kind;
+  BinaryStreamRef Data;
+};
+
+typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray;
+
+} // namespace codeview
+
+template <>
+struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> {
+  typedef void ContextType;
+
+  static Error extract(BinaryStreamRef Stream, uint32_t &Length,
+                       codeview::ModuleDebugFragmentRecord &Info, void *Ctx) {
+    if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info))
+      return EC;
+    Length = Info.getRecordLength();
+    return Error::success();
+  }
+};
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H
Index: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
@@ -14,7 +14,10 @@
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
-#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
 #include "llvm/Support/BinaryStreamArray.h"
 #include "llvm/Support/BinaryStreamReader.h"
 #include "llvm/Support/BinaryStreamRef.h"
@@ -26,105 +29,26 @@
 
 namespace codeview {
 
-struct LineColumnEntry {
-  support::ulittle32_t NameIndex;
-  FixedStreamArray<LineNumberEntry> LineNumbers;
-  FixedStreamArray<ColumnNumberEntry> Columns;
-};
-
-struct FileChecksumEntry {
-  uint32_t FileNameOffset;    // Byte offset of filename in global stringtable.
-  FileChecksumKind Kind;      // The type of checksum.
-  ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
-};
-
-typedef VarStreamArray<LineColumnEntry> LineInfoArray;
-typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
-
 class ModuleDebugFragmentVisitor {
 public:
   virtual ~ModuleDebugFragmentVisitor() = default;
 
-  virtual Error visitUnknown(ModuleDebugFragmentKind Kind,
-                             BinaryStreamRef Data) = 0;
-  virtual Error visitSymbols(BinaryStreamRef Data);
-  virtual Error visitLines(BinaryStreamRef Data,
-                           const LineFragmentHeader *Header,
-                           const LineInfoArray &Lines);
-  virtual Error visitStringTable(BinaryStreamRef Data);
-  virtual Error visitFileChecksums(BinaryStreamRef Data,
-                                   const FileChecksumArray &Checksums);
-  virtual Error visitFrameData(BinaryStreamRef Data);
-  virtual Error visitInlineeLines(BinaryStreamRef Data);
-  virtual Error visitCrossScopeImports(BinaryStreamRef Data);
-  virtual Error visitCrossScopeExports(BinaryStreamRef Data);
-  virtual Error visitILLines(BinaryStreamRef Data);
-  virtual Error visitFuncMDTokenMap(BinaryStreamRef Data);
-  virtual Error visitTypeMDTokenMap(BinaryStreamRef Data);
-  virtual Error visitMergedAssemblyInput(BinaryStreamRef Data);
-  virtual Error visitCoffSymbolRVA(BinaryStreamRef Data);
-};
-
-Error visitModuleDebugFragment(const ModuleDebugFragment &R,
-                               ModuleDebugFragmentVisitor &V);
-} // end namespace codeview
-
-template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> {
-public:
-  typedef const codeview::LineFragmentHeader ContextType;
-
-  static Error extract(BinaryStreamRef Stream, uint32_t &Len,
-                       codeview::LineColumnEntry &Item, ContextType *Header) {
-    using namespace codeview;
-    const LineBlockFragmentHeader *BlockHeader;
-    BinaryStreamReader Reader(Stream);
-    if (auto EC = Reader.readObject(BlockHeader))
-      return EC;
-    bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns);
-    uint32_t LineInfoSize =
-        BlockHeader->NumLines *
-        (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
-    if (BlockHeader->BlockSize < sizeof(LineBlockFragmentHeader))
-      return make_error<CodeViewError>(cv_error_code::corrupt_record,
-                                       "Invalid line block record size");
-    uint32_t Size = BlockHeader->BlockSize - sizeof(LineBlockFragmentHeader);
-    if (LineInfoSize > Size)
-      return make_error<CodeViewError>(cv_error_code::corrupt_record,
-                                       "Invalid line block record size");
-    // The value recorded in BlockHeader->BlockSize includes the size of
-    // LineBlockFragmentHeader.
-    Len = BlockHeader->BlockSize;
-    Item.NameIndex = BlockHeader->NameIndex;
-    if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
-      return EC;
-    if (HasColumn) {
-      if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
-        return EC;
-    }
+  virtual Error visitUnknown(ModuleDebugUnknownFragment &Unknown) {
+    return Error::success();
+  }
+  virtual Error visitLines(ModuleDebugLineFragment &Lines) {
     return Error::success();
   }
-};
-
-template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> {
-public:
-  typedef void ContextType;
 
-  static Error extract(BinaryStreamRef Stream, uint32_t &Len,
-                       codeview::FileChecksumEntry &Item, void *Ctx) {
-    using namespace codeview;
-    const FileChecksum *Header;
-    BinaryStreamReader Reader(Stream);
-    if (auto EC = Reader.readObject(Header))
-      return EC;
-    Item.FileNameOffset = Header->FileNameOffset;
-    Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
-    if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
-      return EC;
-    Len = sizeof(FileChecksum) + Header->ChecksumSize;
+  virtual Error visitFileChecksums(ModuleDebugFileChecksumFragment &Checksums) {
     return Error::success();
   }
 };
 
+Error visitModuleDebugFragment(const ModuleDebugFragmentRecord &R,
+                               ModuleDebugFragmentVisitor &V);
+} // end namespace codeview
+
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H
Index: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
@@ -0,0 +1,92 @@
+//===- ModuleDebugLineFragment.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_MODULEDEBUGLINEFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace codeview {
+
+// Corresponds to the `CV_DebugSLinesHeader_t` structure.
+struct LineFragmentHeader {
+  support::ulittle32_t RelocOffset;  // Code offset of line contribution.
+  support::ulittle16_t RelocSegment; // Code segment of line contribution.
+  support::ulittle16_t Flags;        // See LineFlags enumeration.
+  support::ulittle32_t CodeSize;     // Code size of this line contribution.
+};
+
+// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
+struct LineBlockFragmentHeader {
+  support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
+  support::ulittle32_t NumLines;  // Number of lines
+  support::ulittle32_t BlockSize; // Code size of block, in bytes.
+  // The following two variable length arrays appear immediately after the
+  // header.  The structure definitions follow.
+  // LineNumberEntry   Lines[NumLines];
+  // ColumnNumberEntry Columns[NumLines];
+};
+
+// Corresponds to `CV_Line_t` structure
+struct LineNumberEntry {
+  support::ulittle32_t Offset; // Offset to start of code bytes for line number
+  support::ulittle32_t Flags;  // Start:24, End:7, IsStatement:1
+};
+
+// Corresponds to `CV_Column_t` structure
+struct ColumnNumberEntry {
+  support::ulittle16_t StartColumn;
+  support::ulittle16_t EndColumn;
+};
+
+struct LineColumnEntry {
+  support::ulittle32_t NameIndex;
+  FixedStreamArray<LineNumberEntry> LineNumbers;
+  FixedStreamArray<ColumnNumberEntry> Columns;
+};
+
+class LineColumnExtractor {
+public:
+  typedef const LineFragmentHeader ContextType;
+
+  static Error extract(BinaryStreamRef Stream, uint32_t &Len,
+                       LineColumnEntry &Item, const LineFragmentHeader *Header);
+};
+
+class ModuleDebugLineFragment final : public ModuleDebugFragment {
+  friend class LineColumnExtractor;
+  typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray;
+  typedef LineInfoArray::Iterator Iterator;
+
+public:
+  ModuleDebugLineFragment();
+
+  static bool classof(const ModuleDebugFragment *S) {
+    return S->kind() == ModuleDebugFragmentKind::Lines;
+  }
+
+  Error initialize(BinaryStreamReader Reader);
+
+  Iterator begin() const { return LinesAndColumns.begin(); }
+  Iterator end() const { return LinesAndColumns.end(); }
+
+  const LineFragmentHeader *header() const { return Header; }
+
+private:
+  const LineFragmentHeader *Header = nullptr;
+  LineInfoArray LinesAndColumns;
+};
+}
+}
+
+#endif
Index: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
@@ -0,0 +1,32 @@
+//===- ModuleDebugUnknownFragment.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_MODULEDEBUGUNKNOWNFRAGMENT_H
+#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H
+
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/Support/BinaryStreamRef.h"
+
+namespace llvm {
+namespace codeview {
+
+class ModuleDebugUnknownFragment final : public ModuleDebugFragment {
+public:
+  ModuleDebugUnknownFragment(ModuleDebugFragmentKind Kind, BinaryStreamRef Data)
+      : ModuleDebugFragment(Kind), Data(Data) {}
+
+  BinaryStreamRef getData() const { return Data; }
+
+private:
+  BinaryStreamRef Data;
+};
+}
+}
+
+#endif
Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
===================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
@@ -12,7 +12,7 @@
 
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/DebugInfo/CodeView/CVRecord.h"
-#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/Support/BinaryStreamArray.h"
@@ -25,6 +25,9 @@
 class DbiModuleDescriptor;
 
 class ModuleDebugStream {
+  typedef codeview::ModuleDebugFragmentArray::Iterator
+      LinesAndChecksumsIterator;
+
 public:
   ModuleDebugStream(const DbiModuleDescriptor &Module,
                     std::unique_ptr<msf::MappedBlockStream> Stream);
@@ -37,8 +40,7 @@
   iterator_range<codeview::CVSymbolArray::Iterator>
   symbols(bool *HadError) const;
 
-  iterator_range<codeview::ModuleDebugFragmentArray::Iterator>
-  lines(bool *HadError) const;
+  llvm::iterator_range<LinesAndChecksumsIterator> linesAndChecksums() const;
 
   bool hasLineInfo() const;
 
@@ -56,7 +58,7 @@
   BinaryStreamRef C13LinesSubstream;
   BinaryStreamRef GlobalRefsSubstream;
 
-  codeview::ModuleDebugFragmentArray LineInfo;
+  codeview::ModuleDebugFragmentArray LinesAndChecksums;
 };
 }
 }
Index: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
+++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
@@ -7,8 +7,12 @@
   EnumTables.cpp
   Formatters.cpp
   Line.cpp
+  ModuleDebugFileChecksumFragment.cpp
   ModuleDebugFragment.cpp
+  ModuleDebugFragmentRecord.cpp
   ModuleDebugFragmentVisitor.cpp
+  ModuleDebugLineFragment.cpp
+  ModuleDebugUnknownFragment.cpp
   RecordSerialization.cpp
   SymbolRecordMapping.cpp
   SymbolDumper.cpp
Index: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
@@ -0,0 +1,49 @@
+//===- ModuleDebugFileChecksumFragment.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/ModuleDebugFileChecksumFragment.h"
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+struct FileChecksumEntryHeader {
+  using ulittle32_t = support::ulittle32_t;
+
+  ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
+  uint8_t ChecksumSize;       // Number of bytes of checksum.
+  uint8_t ChecksumKind;       // FileChecksumKind
+                              // Checksum bytes follow.
+};
+
+Error llvm::VarStreamArrayExtractor<FileChecksumEntry>::extract(
+    BinaryStreamRef Stream, uint32_t &Len, FileChecksumEntry &Item, void *Ctx) {
+  BinaryStreamReader Reader(Stream);
+
+  const FileChecksumEntryHeader *Header;
+  if (auto EC = Reader.readObject(Header))
+    return EC;
+
+  Item.FileNameOffset = Header->FileNameOffset;
+  Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
+  if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
+    return EC;
+
+  Len = alignTo(Header->ChecksumSize + sizeof(FileChecksumEntryHeader), 4);
+  return Error::success();
+}
+
+Error ModuleDebugFileChecksumFragment::initialize(BinaryStreamReader Reader) {
+  if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
+    return EC;
+
+  return Error::success();
+}
Index: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
@@ -1,5 +1,4 @@
-//===- ModuleDebugFragment.cpp --------------------------------------*- C++
-//-*-===//
+//===- ModuleDebugFragment.cpp -----------------------------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -10,37 +9,6 @@
 
 #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
 
-#include "llvm/Support/BinaryStreamReader.h"
-
-using namespace llvm;
 using namespace llvm::codeview;
 
-ModuleDebugFragment::ModuleDebugFragment()
-    : Kind(ModuleDebugFragmentKind::None) {}
-
-ModuleDebugFragment::ModuleDebugFragment(ModuleDebugFragmentKind Kind,
-                                         BinaryStreamRef Data)
-    : Kind(Kind), Data(Data) {}
-
-Error ModuleDebugFragment::initialize(BinaryStreamRef Stream,
-                                      ModuleDebugFragment &Info) {
-  const ModuleDebugFragmentHeader *Header;
-  BinaryStreamReader Reader(Stream);
-  if (auto EC = Reader.readObject(Header))
-    return EC;
-
-  ModuleDebugFragmentKind Kind =
-      static_cast<ModuleDebugFragmentKind>(uint32_t(Header->Kind));
-  if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
-    return EC;
-  Info.Kind = Kind;
-  return Error::success();
-}
-
-uint32_t ModuleDebugFragment::getRecordLength() const {
-  return sizeof(ModuleDebugFragmentHeader) + Data.getLength();
-}
-
-ModuleDebugFragmentKind ModuleDebugFragment::kind() const { return Kind; }
-
-BinaryStreamRef ModuleDebugFragment::getRecordData() const { return Data; }
+ModuleDebugFragment::~ModuleDebugFragment() {}
Index: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
@@ -0,0 +1,47 @@
+//===- ModuleDebugFragmentRecord.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/ModuleDebugFragmentRecord.h"
+
+#include "llvm/Support/BinaryStreamReader.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+ModuleDebugFragmentRecord::ModuleDebugFragmentRecord()
+    : Kind(ModuleDebugFragmentKind::None) {}
+
+ModuleDebugFragmentRecord::ModuleDebugFragmentRecord(
+    ModuleDebugFragmentKind Kind, BinaryStreamRef Data)
+    : Kind(Kind), Data(Data) {}
+
+Error ModuleDebugFragmentRecord::initialize(BinaryStreamRef Stream,
+                                            ModuleDebugFragmentRecord &Info) {
+  const ModuleDebugFragmentHeader *Header;
+  BinaryStreamReader Reader(Stream);
+  if (auto EC = Reader.readObject(Header))
+    return EC;
+
+  ModuleDebugFragmentKind Kind =
+      static_cast<ModuleDebugFragmentKind>(uint32_t(Header->Kind));
+  if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
+    return EC;
+  Info.Kind = Kind;
+  return Error::success();
+}
+
+uint32_t ModuleDebugFragmentRecord::getRecordLength() const {
+  return sizeof(ModuleDebugFragmentHeader) + Data.getLength();
+}
+
+ModuleDebugFragmentKind ModuleDebugFragmentRecord::kind() const { return Kind; }
+
+BinaryStreamRef ModuleDebugFragmentRecord::getRecordData() const {
+  return Data;
+}
Index: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
@@ -8,99 +8,36 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
+
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
 #include "llvm/Support/BinaryStreamReader.h"
 #include "llvm/Support/BinaryStreamRef.h"
 
 using namespace llvm;
 using namespace llvm::codeview;
 
-Error ModuleDebugFragmentVisitor::visitSymbols(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::Symbols, Data);
-}
-Error ModuleDebugFragmentVisitor::visitLines(BinaryStreamRef Data,
-                                             const LineFragmentHeader *Header,
-                                             const LineInfoArray &Lines) {
-  return visitUnknown(ModuleDebugFragmentKind::Lines, Data);
-}
-Error ModuleDebugFragmentVisitor::visitStringTable(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::StringTable, Data);
-}
-Error ModuleDebugFragmentVisitor::visitFileChecksums(
-    BinaryStreamRef Data, const FileChecksumArray &Checksums) {
-  return visitUnknown(ModuleDebugFragmentKind::FileChecksums, Data);
-}
-Error ModuleDebugFragmentVisitor::visitFrameData(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::FrameData, Data);
-}
-Error ModuleDebugFragmentVisitor::visitInlineeLines(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::InlineeLines, Data);
-}
-Error ModuleDebugFragmentVisitor::visitCrossScopeImports(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::CrossScopeExports, Data);
-}
-Error ModuleDebugFragmentVisitor::visitCrossScopeExports(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::CrossScopeImports, Data);
-}
-Error ModuleDebugFragmentVisitor::visitILLines(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::ILLines, Data);
-}
-Error ModuleDebugFragmentVisitor::visitFuncMDTokenMap(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::FuncMDTokenMap, Data);
-}
-Error ModuleDebugFragmentVisitor::visitTypeMDTokenMap(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::TypeMDTokenMap, Data);
-}
-Error ModuleDebugFragmentVisitor::visitMergedAssemblyInput(
-    BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::MergedAssemblyInput, Data);
-}
-Error ModuleDebugFragmentVisitor::visitCoffSymbolRVA(BinaryStreamRef Data) {
-  return visitUnknown(ModuleDebugFragmentKind::CoffSymbolRVA, Data);
-}
-
-Error llvm::codeview::visitModuleDebugFragment(const ModuleDebugFragment &R,
-                                               ModuleDebugFragmentVisitor &V) {
+Error llvm::codeview::visitModuleDebugFragment(
+    const ModuleDebugFragmentRecord &R, ModuleDebugFragmentVisitor &V) {
+  BinaryStreamReader Reader(R.getRecordData());
   switch (R.kind()) {
-  case ModuleDebugFragmentKind::Symbols:
-    return V.visitSymbols(R.getRecordData());
   case ModuleDebugFragmentKind::Lines: {
-    BinaryStreamReader Reader(R.getRecordData());
-    const LineFragmentHeader *Header;
-    if (auto EC = Reader.readObject(Header))
+    ModuleDebugLineFragment Fragment;
+    if (auto EC = Fragment.initialize(Reader))
       return EC;
-    LineInfoArray LineInfos;
-    if (auto EC = Reader.readArray(LineInfos, Reader.bytesRemaining(), Header))
-      return EC;
-    return V.visitLines(R.getRecordData(), Header, LineInfos);
+
+    return V.visitLines(Fragment);
   }
-  case ModuleDebugFragmentKind::StringTable:
-    return V.visitStringTable(R.getRecordData());
   case ModuleDebugFragmentKind::FileChecksums: {
-    BinaryStreamReader Reader(R.getRecordData());
-    FileChecksumArray Checksums;
-    if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
+    ModuleDebugFileChecksumFragment Fragment;
+    if (auto EC = Fragment.initialize(Reader))
       return EC;
-    return V.visitFileChecksums(R.getRecordData(), Checksums);
+
+    return V.visitFileChecksums(Fragment);
+  }
+  default: {
+    ModuleDebugUnknownFragment Fragment(R.kind(), R.getRecordData());
+    return V.visitUnknown(Fragment);
   }
-  case ModuleDebugFragmentKind::FrameData:
-    return V.visitFrameData(R.getRecordData());
-  case ModuleDebugFragmentKind::InlineeLines:
-    return V.visitInlineeLines(R.getRecordData());
-  case ModuleDebugFragmentKind::CrossScopeImports:
-    return V.visitCrossScopeImports(R.getRecordData());
-  case ModuleDebugFragmentKind::CrossScopeExports:
-    return V.visitCrossScopeExports(R.getRecordData());
-  case ModuleDebugFragmentKind::ILLines:
-    return V.visitILLines(R.getRecordData());
-  case ModuleDebugFragmentKind::FuncMDTokenMap:
-    return V.visitFuncMDTokenMap(R.getRecordData());
-  case ModuleDebugFragmentKind::TypeMDTokenMap:
-    return V.visitTypeMDTokenMap(R.getRecordData());
-  case ModuleDebugFragmentKind::MergedAssemblyInput:
-    return V.visitMergedAssemblyInput(R.getRecordData());
-  case ModuleDebugFragmentKind::CoffSymbolRVA:
-    return V.visitCoffSymbolRVA(R.getRecordData());
-  default:
-    return V.visitUnknown(R.kind(), R.getRecordData());
   }
 }
Index: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
@@ -0,0 +1,63 @@
+//===- ModuleDebugLineFragment.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/ModuleDebugLineFragment.h"
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error LineColumnExtractor::extract(BinaryStreamRef Stream, uint32_t &Len,
+                                   LineColumnEntry &Item,
+                                   const LineFragmentHeader *Header) {
+  using namespace codeview;
+  const LineBlockFragmentHeader *BlockHeader;
+  BinaryStreamReader Reader(Stream);
+  if (auto EC = Reader.readObject(BlockHeader))
+    return EC;
+  bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns);
+  uint32_t LineInfoSize =
+      BlockHeader->NumLines *
+      (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
+  if (BlockHeader->BlockSize < sizeof(LineBlockFragmentHeader))
+    return make_error<CodeViewError>(cv_error_code::corrupt_record,
+                                     "Invalid line block record size");
+  uint32_t Size = BlockHeader->BlockSize - sizeof(LineBlockFragmentHeader);
+  if (LineInfoSize > Size)
+    return make_error<CodeViewError>(cv_error_code::corrupt_record,
+                                     "Invalid line block record size");
+  // The value recorded in BlockHeader->BlockSize includes the size of
+  // LineBlockFragmentHeader.
+  Len = BlockHeader->BlockSize;
+  Item.NameIndex = BlockHeader->NameIndex;
+  if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
+    return EC;
+  if (HasColumn) {
+    if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
+      return EC;
+  }
+  return Error::success();
+}
+
+ModuleDebugLineFragment::ModuleDebugLineFragment()
+    : ModuleDebugFragment(ModuleDebugFragmentKind::Lines) {}
+
+Error ModuleDebugLineFragment::initialize(BinaryStreamReader Reader) {
+  if (auto EC = Reader.readObject(Header))
+    return EC;
+
+  if (auto EC =
+          Reader.readArray(LinesAndColumns, Reader.bytesRemaining(), Header))
+    return EC;
+
+  return Error::success();
+}
Index: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
+++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
@@ -0,0 +1,10 @@
+//===- ModuleDebugUnknownFragment.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/ModuleDebugUnknownFragment.h"
\ No newline at end of file
Index: llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
===================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
+++ llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
@@ -21,6 +21,7 @@
 #include <cstdint>
 
 using namespace llvm;
+using namespace llvm::codeview;
 using namespace llvm::msf;
 using namespace llvm::pdb;
 
@@ -54,7 +55,8 @@
     return EC;
 
   BinaryStreamReader LineReader(C13LinesSubstream);
-  if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining()))
+  if (auto EC =
+          LineReader.readArray(LinesAndChecksums, LineReader.bytesRemaining()))
     return EC;
 
   uint32_t GlobalRefsSize;
@@ -77,13 +79,13 @@
   return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
 }
 
-iterator_range<codeview::ModuleDebugFragmentArray::Iterator>
-ModuleDebugStream::lines(bool *HadError) const {
-  return make_range(LineInfo.begin(HadError), LineInfo.end());
+llvm::iterator_range<ModuleDebugStream::LinesAndChecksumsIterator>
+ModuleDebugStream::linesAndChecksums() const {
+  return make_range(LinesAndChecksums.begin(), LinesAndChecksums.end());
 }
 
 bool ModuleDebugStream::hasLineInfo() const {
-  return C13LinesSubstream.getLength() > 0 || LinesSubstream.getLength() > 0;
+  return C13LinesSubstream.getLength() > 0;
 }
 
 Error ModuleDebugStream::commit() { return Error::success(); }
Index: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
===================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -16,7 +16,10 @@
 #include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumper.h"
 #include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
@@ -633,17 +636,15 @@
         }
         if (opts::raw::DumpLineInfo) {
           ListScope SS(P, "LineInfo");
-          bool HadError = false;
           // Define a locally scoped visitor to print the different
           // substream types types.
           class RecordVisitor : public codeview::ModuleDebugFragmentVisitor {
           public:
             RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
-            Error visitUnknown(ModuleDebugFragmentKind Kind,
-                               BinaryStreamRef Stream) override {
+            Error visitUnknown(ModuleDebugUnknownFragment &Fragment) override {
               DictScope DD(P, "Unknown");
               ArrayRef<uint8_t> Data;
-              BinaryStreamReader R(Stream);
+              BinaryStreamReader R(Fragment.getData());
               if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
                 return make_error<RawError>(
                     raw_error_code::corrupt_file,
@@ -652,9 +653,8 @@
               P.printBinaryBlock("Data", Data);
               return Error::success();
             }
-            Error
-            visitFileChecksums(BinaryStreamRef Data,
-                               const FileChecksumArray &Checksums) override {
+            Error visitFileChecksums(
+                ModuleDebugFileChecksumFragment &Checksums) override {
               DictScope DD(P, "FileChecksums");
               for (const auto &C : Checksums) {
                 DictScope DDD(P, "Checksum");
@@ -669,9 +669,7 @@
               return Error::success();
             }
 
-            Error visitLines(BinaryStreamRef Data,
-                             const LineFragmentHeader *Header,
-                             const LineInfoArray &Lines) override {
+            Error visitLines(ModuleDebugLineFragment &Lines) override {
               DictScope DD(P, "Lines");
               for (const auto &L : Lines) {
                 if (auto Result = getFileNameForOffset2(L.NameIndex))
@@ -720,7 +718,7 @@
           };
 
           RecordVisitor V(P, File);
-          for (const auto &L : ModS.lines(&HadError)) {
+          for (const auto &L : ModS.linesAndChecksums()) {
             if (auto EC = codeview::visitModuleDebugFragment(L, V))
               return EC;
           }
Index: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
===================================================================
--- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
+++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
@@ -13,8 +13,11 @@
 #include "llvm-pdbdump.h"
 
 #include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
 #include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
@@ -24,6 +27,7 @@
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 
 using namespace llvm;
+using namespace llvm::codeview;
 using namespace llvm::pdb;
 
 YAMLOutputStyle::YAMLOutputStyle(PDBFile &File)
@@ -75,19 +79,17 @@
 }
 
 namespace {
-class C13SubstreamVisitor : public codeview::ModuleDebugFragmentVisitor {
+class C13SubstreamVisitor : public ModuleDebugFragmentVisitor {
 public:
   C13SubstreamVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F)
       : Info(Info), F(F) {}
 
-  Error visitUnknown(codeview::ModuleDebugFragmentKind Kind,
-                     BinaryStreamRef Stream) override {
+  Error visitUnknown(ModuleDebugUnknownFragment &Fragment) override {
     return Error::success();
   }
 
   Error
-  visitFileChecksums(BinaryStreamRef Data,
-                     const codeview::FileChecksumArray &Checksums) override {
+  visitFileChecksums(ModuleDebugFileChecksumFragment &Checksums) override {
     for (const auto &C : Checksums) {
       llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry;
       if (auto Result = getGlobalString(C.FileNameOffset))
@@ -102,15 +104,13 @@
     return Error::success();
   }
 
-  Error visitLines(BinaryStreamRef Data,
-                   const codeview::LineFragmentHeader *Header,
-                   const codeview::LineInfoArray &Lines) override {
+  Error visitLines(ModuleDebugLineFragment &Lines) override {
 
-    Info.Lines.CodeSize = Header->CodeSize;
+    Info.Lines.CodeSize = Lines.header()->CodeSize;
     Info.Lines.Flags =
-        static_cast<codeview::LineFlags>(uint16_t(Header->Flags));
-    Info.Lines.RelocOffset = Header->RelocOffset;
-    Info.Lines.RelocSegment = Header->RelocSegment;
+        static_cast<codeview::LineFlags>(uint16_t(Lines.header()->Flags));
+    Info.Lines.RelocOffset = Lines.header()->RelocOffset;
+    Info.Lines.RelocSegment = Lines.header()->RelocSegment;
 
     for (const auto &L : Lines) {
       llvm::pdb::yaml::PdbSourceLineBlock Block;
@@ -170,9 +170,8 @@
     return None;
 
   yaml::PdbSourceFileInfo Info;
-  bool Error = false;
   C13SubstreamVisitor Visitor(Info, File);
-  for (auto &Frag : ModS.lines(&Error)) {
+  for (auto &Frag : ModS.linesAndChecksums()) {
     if (auto E = codeview::visitModuleDebugFragment(Frag, Visitor))
       return std::move(E);
   }
Index: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
===================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
@@ -25,6 +25,7 @@
 #include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
@@ -985,29 +986,22 @@
 void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) {
   BinaryByteStream S(Subsection, llvm::support::little);
   BinaryStreamReader SR(S);
-  while (!SR.empty()) {
+  ModuleDebugFileChecksumFragment Checksums;
+  error(Checksums.initialize(SR));
+
+  for (auto &FC : Checksums) {
     DictScope S(W, "FileChecksum");
-    const FileChecksum *FC;
-    error(SR.readObject(FC));
-    if (FC->FileNameOffset >= CVStringTable.size())
+
+    if (FC.FileNameOffset >= CVStringTable.size())
       error(object_error::parse_failed);
     StringRef Filename =
-        CVStringTable.drop_front(FC->FileNameOffset).split('\0').first;
-    W.printHex("Filename", Filename, FC->FileNameOffset);
-    W.printHex("ChecksumSize", FC->ChecksumSize);
-    W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind),
+        CVStringTable.drop_front(FC.FileNameOffset).split('\0').first;
+    W.printHex("Filename", Filename, FC.FileNameOffset);
+    W.printHex("ChecksumSize", FC.Checksum.size());
+    W.printEnum("ChecksumKind", uint8_t(FC.Kind),
                 makeArrayRef(FileChecksumKindNames));
-    if (FC->ChecksumSize >= SR.bytesRemaining())
-      error(object_error::parse_failed);
-    ArrayRef<uint8_t> ChecksumBytes;
-    error(SR.readBytes(ChecksumBytes, FC->ChecksumSize));
-    W.printBinary("ChecksumBytes", ChecksumBytes);
-    unsigned PaddedSize = alignTo(FC->ChecksumSize + sizeof(FileChecksum), 4) -
-                          sizeof(FileChecksum);
-    PaddedSize -= ChecksumBytes.size();
-    if (PaddedSize > SR.bytesRemaining())
-      error(object_error::parse_failed);
-    error(SR.skip(PaddedSize));
+
+    W.printBinary("ChecksumBytes", FC.Checksum);
   }
 }