[llvm] r301557 - [CodeView] Isolate Debug Info Fragments into standalone classes.

Aaron Ballman via llvm-commits llvm-commits at lists.llvm.org
Tue May 9 07:20:24 PDT 2017


On Thu, Apr 27, 2017 at 12:12 PM, Zachary Turner via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: zturner
> Date: Thu Apr 27 11:12:16 2017
> New Revision: 301557
>
> URL: http://llvm.org/viewvc/llvm-project?rev=301557&view=rev
> Log:
> [CodeView] Isolate Debug Info Fragments into standalone classes.
>
> Previously parsing of these were all grouped together into a
> single master class that could parse any type of debug info
> fragment.
>
> With writing forthcoming, the complexity of each individual
> fragment is enough to warrant them having their own classes so
> that reading and writing of each fragment type can be grouped
> together, but isolated from the code for reading and writing
> other fragment types.
>
> In doing so, I found a place where parsing code was duplicated
> for the FileChecksums fragment, across llvm-readobj and the
> CodeView library, and one of the implementations had a bug.
> Now that the codepaths are merged, the bug is resolved.
>
> Differential Revision: https://reviews.llvm.org/D32547
>
> Added:
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
> Modified:
>     llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
>     llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
>     llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
>     llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
>     llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
>     llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
>     llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
>     llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
>     llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/Line.h Thu Apr 27 11:12:16 2017
> @@ -141,13 +141,6 @@ struct InlineeSourceLine {
>    //   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
>
>
> Added: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h (added)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h Thu Apr 27 11:12:16 2017
> @@ -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
>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h Thu Apr 27 11:12:16 2017
> @@ -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
>
> Added: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h (added)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h Thu Apr 27 11:12:16 2017
> @@ -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
>
> Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h Thu Apr 27 11:12:16 2017
> @@ -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 llvm {
>
>  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
>
> Added: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h (added)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h Thu Apr 27 11:12:16 2017
> @@ -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
>
> Added: llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h (added)
> +++ llvm/trunk/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h Thu Apr 27 11:12:16 2017
> @@ -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
>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h Thu Apr 27 11:12:16 2017
> @@ -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 PDBFile;
>  class DbiModuleDescriptor;
>
>  class ModuleDebugStream {
> +  typedef codeview::ModuleDebugFragmentArray::Iterator
> +      LinesAndChecksumsIterator;
> +
>  public:
>    ModuleDebugStream(const DbiModuleDescriptor &Module,
>                      std::unique_ptr<msf::MappedBlockStream> Stream);
> @@ -37,8 +40,7 @@ public:
>    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 @@ private:
>    BinaryStreamRef C13LinesSubstream;
>    BinaryStreamRef GlobalRefsSubstream;
>
> -  codeview::ModuleDebugFragmentArray LineInfo;
> +  codeview::ModuleDebugFragmentArray LinesAndChecksums;
>  };
>  }
>  }
>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt (original)
> +++ llvm/trunk/lib/DebugInfo/CodeView/CMakeLists.txt Thu Apr 27 11:12:16 2017
> @@ -7,8 +7,12 @@ add_llvm_library(LLVMDebugInfoCodeView
>    EnumTables.cpp
>    Formatters.cpp
>    Line.cpp
> +  ModuleDebugFileChecksumFragment.cpp
>    ModuleDebugFragment.cpp
> +  ModuleDebugFragmentRecord.cpp
>    ModuleDebugFragmentVisitor.cpp
> +  ModuleDebugLineFragment.cpp
> +  ModuleDebugUnknownFragment.cpp
>    RecordSerialization.cpp
>    SymbolRecordMapping.cpp
>    SymbolDumper.cpp
>
> Added: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp (added)
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.cpp Thu Apr 27 11:12:16 2017
> @@ -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();
> +}
>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragment.cpp Thu Apr 27 11:12:16 2017
> @@ -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() {}
>
> Added: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp (added)
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentRecord.cpp Thu Apr 27 11:12:16 2017
> @@ -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;
> +}
>
> Modified: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugFragmentVisitor.cpp Thu Apr 27 11:12:16 2017
> @@ -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());
>    }
>  }
>
> Added: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp (added)
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugLineFragment.cpp Thu Apr 27 11:12:16 2017
> @@ -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();
> +}
>
> Added: llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp?rev=301557&view=auto
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp (added)
> +++ llvm/trunk/lib/DebugInfo/CodeView/ModuleDebugUnknownFragment.cpp Thu Apr 27 11:12:16 2017
> @@ -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

This file was commit with no newline, but more importantly, why is
this file needed at all? It's generating diagnostics with link.exe
because the resulting object file contains no previously undefined
public symbols.

~Aaron

>
> Modified: llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp Thu Apr 27 11:12:16 2017
> @@ -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 @@ Error ModuleDebugStream::reload() {
>      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 @@ ModuleDebugStream::symbols(bool *HadErro
>    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(); }
>
> Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
> +++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Thu Apr 27 11:12:16 2017
> @@ -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 @@ Error LLVMOutputStyle::dumpDbiStream() {
>          }
>          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 @@ Error LLVMOutputStyle::dumpDbiStream() {
>                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 @@ Error LLVMOutputStyle::dumpDbiStream() {
>                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 @@ Error LLVMOutputStyle::dumpDbiStream() {
>            };
>
>            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;
>            }
>
> Modified: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp (original)
> +++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp Thu Apr 27 11:12:16 2017
> @@ -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 @@ Error YAMLOutputStyle::dump() {
>  }
>
>  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 @@ public:
>      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 @@ YAMLOutputStyle::getFileLineInfo(const p
>      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);
>    }
>
> Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=301557&r1=301556&r2=301557&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
> +++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Thu Apr 27 11:12:16 2017
> @@ -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::printCodeViewSymbolsSub
>  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);
>    }
>  }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list