]> granicus.if.org Git - llvm/commitdiff
[llvm-pdbdump] Dump File / Line Info to YAML.
authorZachary Turner <zturner@google.com>
Tue, 25 Apr 2017 20:22:02 +0000 (20:22 +0000)
committerZachary Turner <zturner@google.com>
Tue, 25 Apr 2017 20:22:02 +0000 (20:22 +0000)
We were already parsing and dumping this to the human readable
format, but not to the YAML format.  This does so, in preparation
for reading it in and reconstructing the line information from
YAML.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301357 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/llvm/DebugInfo/CodeView/CodeView.h
include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
include/llvm/DebugInfo/PDB/Native/ModStream.h
include/llvm/Support/YAMLTraits.h
lib/DebugInfo/PDB/Native/ModStream.cpp
test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test [new file with mode: 0644]
tools/llvm-pdbdump/PdbYaml.cpp
tools/llvm-pdbdump/PdbYaml.h
tools/llvm-pdbdump/YAMLOutputStyle.cpp
tools/llvm-pdbdump/YAMLOutputStyle.h
tools/llvm-pdbdump/llvm-pdbdump.cpp
tools/llvm-pdbdump/llvm-pdbdump.h

index 2791c9dc374651b8c1289cecdb1cc323f36b1dcd..e599f8a19e347d0409dd48a319624b9d71f9c515 100644 (file)
@@ -546,7 +546,7 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland };
 // These values correspond to the CV_SourceChksum_t enumeration.
 enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 };
 
-enum LineFlags : uint32_t {
+enum LineFlags : uint16_t {
   HaveColumns = 1, // CV_LINES_HAVE_COLUMNS
 };
 }
index 1a40654a3f3379eb1e2a1da77d899bfb8e946091..31344a9427db5f6e58145172b2db81a5a780661a 100644 (file)
@@ -81,7 +81,7 @@ public:
     BinaryStreamReader Reader(Stream);
     if (auto EC = Reader.readObject(BlockHeader))
       return EC;
-    bool HasColumn = Header->Flags & LineFlags::HaveColumns;
+    bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns);
     uint32_t LineInfoSize =
         BlockHeader->NumLines *
         (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
index d65e195dbb95b080f5183f6b4d32d7c75d905c2d..b12d4ff375f32f7450e2c3b4d80361beb86b2991 100644 (file)
@@ -40,6 +40,8 @@ public:
   iterator_range<codeview::ModuleSubstreamArray::Iterator>
   lines(bool *HadError) const;
 
+  bool hasLineInfo() const;
+
   Error commit();
 
 private:
index 6d02e4aba48a7b94a3d8a2744f6a0420b4a4cbb2..ffea679fab828feeaa050b3d22f03fd2bd2a9129 100644 (file)
@@ -606,7 +606,7 @@ public:
   template <typename T>
   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
-      Val = Val | ConstVal;
+      Val = static_cast<T>(Val | ConstVal);
     }
   }
 
@@ -614,7 +614,7 @@ public:
   template <typename T>
   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
-      Val = Val | ConstVal;
+      Val = static_cast<T>(Val | ConstVal);
     }
   }
 
index 08798cf0ed286f63fd3f101393d0173f345492f7..e87e2c40759327b11a1d96375ec2c76c8dfef1d9 100644 (file)
@@ -82,4 +82,8 @@ ModStream::lines(bool *HadError) const {
   return make_range(LineInfo.begin(HadError), LineInfo.end());
 }
 
+bool ModStream::hasLineInfo() const {
+  return C13LinesSubstream.getLength() > 0 || LinesSubstream.getLength() > 0;
+}
+
 Error ModStream::commit() { return Error::success(); }
diff --git a/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test b/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test
new file mode 100644 (file)
index 0000000..016d524
--- /dev/null
@@ -0,0 +1,59 @@
+; RUN: llvm-pdbdump pdb2yaml -dbi-module-lines %p/Inputs/empty.pdb \\r
+; RUN:   | FileCheck -check-prefix=YAML %s\r
+\r
+\r
+YAML: ---\r
+YAML: MSF:\r
+YAML:   SuperBlock:\r
+YAML:     BlockSize:       4096\r
+YAML:     FreeBlockMap:    2\r
+YAML:     NumBlocks:       25\r
+YAML:     NumDirectoryBytes: 136\r
+YAML:     Unknown1:        0\r
+YAML:     BlockMapAddr:    24\r
+YAML:   NumDirectoryBlocks: 1\r
+YAML:   DirectoryBlocks: [ 23 ]\r
+YAML:   NumStreams:      0\r
+YAML:   FileSize:        102400\r
+YAML: DbiStream:\r
+YAML:   VerHeader:       V70\r
+YAML:   Age:             1\r
+YAML:   BuildNumber:     35840\r
+YAML:   PdbDllVersion:   31101\r
+YAML:   PdbDllRbld:      0\r
+YAML:   Flags:           1\r
+YAML:   MachineType:     x86\r
+YAML:   Modules:\r
+YAML:   - Module:          'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'\r
+YAML:     ObjFile:         'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'\r
+YAML:     SourceFiles:\r
+YAML:       - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'\r
+YAML:     LineInfo:\r
+YAML:       Lines:\r
+YAML:         CodeSize:        10\r
+YAML:         Flags:           [  ]\r
+YAML:         RelocOffset:     16\r
+YAML:      RelocSegment:    1\r
+YAML:      LineInfo:\r
+YAML:        - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'\r
+YAML:          Lines:\r
+YAML:            - Offset:          0\r
+YAML:              LineStart:       5\r
+YAML:              IsStatement:     true\r
+YAML:              EndDelta:        5\r
+YAML:            - Offset:          3\r
+YAML:              LineStart:       6\r
+YAML:              IsStatement:     true\r
+YAML:              EndDelta:        6\r
+YAML:            - Offset:          8\r
+YAML:              LineStart:       7\r
+YAML:              IsStatement:     true\r
+YAML:              EndDelta:        7\r
+YAML:          Columns:\r
+YAML:     Checksums:\r
+YAML:       - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'\r
+YAML:         Kind:            MD5\r
+YAML:         Checksum:        A0A5BD0D3ECD93FC29D19DE826FBF4BC\r
+YAML:  - Module:          '* Linker *'\r
+YAML:    ObjFile:         ''\r
+YAML: ...
\ No newline at end of file
index e2c4ee967ed36e12bbc5a5804dda6e7287fbb032..65a5a9142d20a2b7e50e61f4f488f12274d5e24d 100644 (file)
@@ -13,6 +13,7 @@
 #include "YamlSymbolDumper.h"
 #include "YamlTypeDumper.h"
 
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
@@ -35,6 +36,10 @@ LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceFileChecksumEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceColumnEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSourceLineBlock)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSymbolRecord)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
@@ -145,7 +150,38 @@ template <> struct ScalarEnumerationTraits<llvm::pdb::PdbRaw_FeatureSig> {
     io.enumCase(Features, "VC140", PdbRaw_FeatureSig::VC140);
   }
 };
+
+template <> struct ScalarEnumerationTraits<llvm::codeview::FileChecksumKind> {
+  static void enumeration(IO &io, llvm::codeview::FileChecksumKind &Kind) {
+    io.enumCase(Kind, "None", llvm::codeview::FileChecksumKind::None);
+    io.enumCase(Kind, "MD5", llvm::codeview::FileChecksumKind::MD5);
+    io.enumCase(Kind, "SHA1", llvm::codeview::FileChecksumKind::SHA1);
+    io.enumCase(Kind, "SHA256", llvm::codeview::FileChecksumKind::SHA256);
+  }
+};
+
+template <> struct ScalarBitSetTraits<llvm::codeview::LineFlags> {
+  static void bitset(IO &io, llvm::codeview::LineFlags &Flags) {
+    io.bitSetCase(Flags, "HasColumnInfo",
+                  llvm::codeview::LineFlags::HaveColumns);
+    io.enumFallback<Hex16>(Flags);
+  }
+};
+}
 }
+
+void ScalarTraits<HexFormattedString>::output(const HexFormattedString &Value,
+                                              void *ctx, raw_ostream &Out) {
+  StringRef Bytes(reinterpret_cast<const char *>(Value.Bytes.data()),
+                  Value.Bytes.size());
+  Out << toHex(Bytes);
+}
+
+StringRef ScalarTraits<HexFormattedString>::input(StringRef Scalar, void *ctxt,
+                                                  HexFormattedString &Value) {
+  std::string H = fromHex(Scalar);
+  Value.Bytes.assign(H.begin(), H.end());
+  return StringRef();
 }
 
 void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
@@ -255,9 +291,65 @@ void MappingContextTraits<PdbDbiModuleInfo, pdb::yaml::SerializationContext>::ma
   IO.mapRequired("Module", Obj.Mod);
   IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod);
   IO.mapOptional("SourceFiles", Obj.SourceFiles);
+  IO.mapOptionalWithContext("LineInfo", Obj.FileLineInfo, Context);
   IO.mapOptionalWithContext("Modi", Obj.Modi, Context);
 }
 
+void MappingContextTraits<pdb::yaml::PdbSourceLineEntry,
+                          pdb::yaml::SerializationContext>::
+    mapping(IO &IO, PdbSourceLineEntry &Obj,
+            pdb::yaml::SerializationContext &Context) {
+  IO.mapRequired("Offset", Obj.Offset);
+  IO.mapRequired("LineStart", Obj.LineStart);
+  IO.mapRequired("IsStatement", Obj.IsStatement);
+  IO.mapRequired("EndDelta", Obj.EndDelta);
+}
+
+void MappingContextTraits<pdb::yaml::PdbSourceColumnEntry,
+                          pdb::yaml::SerializationContext>::
+    mapping(IO &IO, PdbSourceColumnEntry &Obj,
+            pdb::yaml::SerializationContext &Context) {
+  IO.mapRequired("StartColumn", Obj.StartColumn);
+  IO.mapRequired("EndColumn", Obj.EndColumn);
+};
+
+void MappingContextTraits<pdb::yaml::PdbSourceLineBlock,
+                          pdb::yaml::SerializationContext>::
+    mapping(IO &IO, PdbSourceLineBlock &Obj,
+            pdb::yaml::SerializationContext &Context) {
+  IO.mapRequired("FileName", Obj.FileName);
+  IO.mapRequired("Lines", Obj.Lines, Context);
+  IO.mapRequired("Columns", Obj.Columns, Context);
+};
+
+void MappingContextTraits<pdb::yaml::PdbSourceFileChecksumEntry,
+                          pdb::yaml::SerializationContext>::
+    mapping(IO &IO, PdbSourceFileChecksumEntry &Obj,
+            pdb::yaml::SerializationContext &Context) {
+  IO.mapRequired("FileName", Obj.FileName);
+  IO.mapRequired("Kind", Obj.Kind);
+  IO.mapRequired("Checksum", Obj.ChecksumBytes);
+};
+
+void MappingContextTraits<pdb::yaml::PdbSourceLineInfo,
+                          pdb::yaml::SerializationContext>::
+    mapping(IO &IO, PdbSourceLineInfo &Obj,
+            pdb::yaml::SerializationContext &Context) {
+  IO.mapRequired("CodeSize", Obj.CodeSize);
+  IO.mapRequired("Flags", Obj.Flags);
+  IO.mapRequired("RelocOffset", Obj.RelocOffset);
+  IO.mapRequired("RelocSegment", Obj.RelocSegment);
+  IO.mapRequired("LineInfo", Obj.LineInfo, Context);
+};
+
+void MappingContextTraits<pdb::yaml::PdbSourceFileInfo,
+                          pdb::yaml::SerializationContext>::
+    mapping(IO &IO, PdbSourceFileInfo &Obj,
+            pdb::yaml::SerializationContext &Context) {
+  IO.mapOptionalWithContext("Lines", Obj.Lines, Context);
+  IO.mapOptionalWithContext("Checksums", Obj.FileChecksums, Context);
+};
+
 void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
     mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
             pdb::yaml::SerializationContext &Context) {
index 2c4cd237f8d7f69187dae24a0741954ee6f9ee35..96e0583ca23d1af4b84df8b0b303db9221da7d2c 100644 (file)
@@ -65,10 +65,53 @@ struct PdbModiStream {
   std::vector<PdbSymbolRecord> Symbols;
 };
 
+struct PdbSourceLineEntry {
+  uint32_t Offset;
+  uint32_t LineStart;
+  uint32_t EndDelta;
+  bool IsStatement;
+};
+
+struct PdbSourceColumnEntry {
+  uint16_t StartColumn;
+  uint16_t EndColumn;
+};
+
+struct PdbSourceLineBlock {
+  StringRef FileName;
+  std::vector<PdbSourceLineEntry> Lines;
+  std::vector<PdbSourceColumnEntry> Columns;
+};
+
+struct HexFormattedString {
+  std::vector<uint8_t> Bytes;
+};
+
+struct PdbSourceFileChecksumEntry {
+  StringRef FileName;
+  codeview::FileChecksumKind Kind;
+  HexFormattedString ChecksumBytes;
+};
+
+struct PdbSourceLineInfo {
+  uint32_t RelocOffset;
+  uint32_t RelocSegment;
+  codeview::LineFlags Flags;
+  uint32_t CodeSize;
+
+  std::vector<PdbSourceLineBlock> LineInfo;
+};
+
+struct PdbSourceFileInfo {
+  PdbSourceLineInfo Lines;
+  std::vector<PdbSourceFileChecksumEntry> FileChecksums;
+};
+
 struct PdbDbiModuleInfo {
   StringRef Obj;
   StringRef Mod;
   std::vector<StringRef> SourceFiles;
+  Optional<PdbSourceFileInfo> FileLineInfo;
   Optional<PdbModiStream> Modi;
 };
 
@@ -165,6 +208,56 @@ template <> struct MappingContextTraits<pdb::yaml::PdbDbiModuleInfo, pdb::yaml::
   static void mapping(IO &IO, pdb::yaml::PdbDbiModuleInfo &Obj, pdb::yaml::SerializationContext &Context);
 };
 
+template <>
+struct MappingContextTraits<pdb::yaml::PdbSourceLineEntry,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSourceLineEntry &Obj,
+                      pdb::yaml::SerializationContext &Context);
+};
+
+template <>
+struct MappingContextTraits<pdb::yaml::PdbSourceColumnEntry,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSourceColumnEntry &Obj,
+                      pdb::yaml::SerializationContext &Context);
+};
+
+template <>
+struct MappingContextTraits<pdb::yaml::PdbSourceLineBlock,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSourceLineBlock &Obj,
+                      pdb::yaml::SerializationContext &Context);
+};
+
+template <>
+struct MappingContextTraits<pdb::yaml::PdbSourceFileChecksumEntry,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSourceFileChecksumEntry &Obj,
+                      pdb::yaml::SerializationContext &Context);
+};
+
+template <> struct ScalarTraits<pdb::yaml::HexFormattedString> {
+  static void output(const pdb::yaml::HexFormattedString &Value, void *ctx,
+                     llvm::raw_ostream &Out);
+  static StringRef input(StringRef Scalar, void *ctxt,
+                         pdb::yaml::HexFormattedString &Value);
+  static bool mustQuote(StringRef) { return false; }
+};
+
+template <>
+struct MappingContextTraits<pdb::yaml::PdbSourceLineInfo,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSourceLineInfo &Obj,
+                      pdb::yaml::SerializationContext &Context);
+};
+
+template <>
+struct MappingContextTraits<pdb::yaml::PdbSourceFileInfo,
+                            pdb::yaml::SerializationContext> {
+  static void mapping(IO &IO, pdb::yaml::PdbSourceFileInfo &Obj,
+                      pdb::yaml::SerializationContext &Context);
+};
+
 template <>
 struct MappingContextTraits<pdb::yaml::PdbTpiRecord,
                             pdb::yaml::SerializationContext> {
index 5b53d2137166a02c288e2e0b418c74288b3f947f..b329de265e72061536b01b409bcfe3466f042b9b 100644 (file)
@@ -12,6 +12,9 @@
 #include "PdbYaml.h"
 #include "llvm-pdbdump.h"
 
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
+#include "llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
@@ -33,8 +36,13 @@ Error YAMLOutputStyle::dump() {
     opts::pdb2yaml::StreamMetadata = true;
   if (opts::pdb2yaml::DbiModuleSyms)
     opts::pdb2yaml::DbiModuleInfo = true;
+
+  if (opts::pdb2yaml::DbiModuleSourceLineInfo)
+    opts::pdb2yaml::DbiModuleSourceFileInfo = true;
+
   if (opts::pdb2yaml::DbiModuleSourceFileInfo)
     opts::pdb2yaml::DbiModuleInfo = true;
+
   if (opts::pdb2yaml::DbiModuleInfo)
     opts::pdb2yaml::DbiStream = true;
 
@@ -66,6 +74,112 @@ Error YAMLOutputStyle::dump() {
   return Error::success();
 }
 
+namespace {
+class C13SubstreamVisitor : public codeview::IModuleSubstreamVisitor {
+public:
+  C13SubstreamVisitor(llvm::pdb::yaml::PdbSourceFileInfo &Info, PDBFile &F)
+      : Info(Info), F(F) {}
+
+  Error visitUnknown(codeview::ModuleSubstreamKind Kind,
+                     BinaryStreamRef Stream) override {
+    return Error::success();
+  }
+
+  Error
+  visitFileChecksums(BinaryStreamRef Data,
+                     const codeview::FileChecksumArray &Checksums) override {
+    for (const auto &C : Checksums) {
+      llvm::pdb::yaml::PdbSourceFileChecksumEntry Entry;
+      if (auto Result = getGlobalString(C.FileNameOffset))
+        Entry.FileName = *Result;
+      else
+        return Result.takeError();
+
+      Entry.Kind = C.Kind;
+      Entry.ChecksumBytes.Bytes = C.Checksum;
+      Info.FileChecksums.push_back(Entry);
+    }
+    return Error::success();
+  }
+
+  Error visitLines(BinaryStreamRef Data,
+                   const codeview::LineSubstreamHeader *Header,
+                   const codeview::LineInfoArray &Lines) override {
+
+    Info.Lines.CodeSize = Header->CodeSize;
+    Info.Lines.Flags =
+        static_cast<codeview::LineFlags>(uint16_t(Header->Flags));
+    Info.Lines.RelocOffset = Header->RelocOffset;
+    Info.Lines.RelocSegment = Header->RelocSegment;
+
+    for (const auto &L : Lines) {
+      llvm::pdb::yaml::PdbSourceLineBlock Block;
+
+      if (auto Result = getDbiFileName(L.NameIndex))
+        Block.FileName = *Result;
+      else
+        return Result.takeError();
+
+      for (const auto &N : L.LineNumbers) {
+        llvm::pdb::yaml::PdbSourceLineEntry Line;
+        Line.Offset = N.Offset;
+        codeview::LineInfo LI(N.Flags);
+        Line.LineStart = LI.getStartLine();
+        Line.EndDelta = LI.getEndLine();
+        Line.IsStatement = LI.isStatement();
+        Block.Lines.push_back(Line);
+      }
+
+      if (Info.Lines.Flags & codeview::LineFlags::HaveColumns) {
+        for (const auto &C : L.Columns) {
+          llvm::pdb::yaml::PdbSourceColumnEntry Column;
+          Column.StartColumn = C.StartColumn;
+          Column.EndColumn = C.EndColumn;
+          Block.Columns.push_back(Column);
+        }
+      }
+
+      Info.Lines.LineInfo.push_back(Block);
+    }
+    return Error::success();
+  }
+
+private:
+  Expected<StringRef> getGlobalString(uint32_t Offset) {
+    auto ST = F.getStringTable();
+    if (!ST)
+      return ST.takeError();
+
+    return ST->getStringForID(Offset);
+  }
+  Expected<StringRef> getDbiFileName(uint32_t Offset) {
+    auto DS = F.getPDBDbiStream();
+    if (!DS)
+      return DS.takeError();
+    return DS->getFileNameForIndex(Offset);
+  }
+
+  llvm::pdb::yaml::PdbSourceFileInfo &Info;
+  PDBFile &F;
+};
+}
+
+Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
+YAMLOutputStyle::getFileLineInfo(const pdb::ModStream &ModS) {
+  if (!ModS.hasLineInfo())
+    return None;
+
+  yaml::PdbSourceFileInfo Info;
+  bool Error = false;
+  C13SubstreamVisitor Visitor(Info, File);
+  for (auto &Substream : ModS.lines(&Error)) {
+    if (auto E = codeview::visitModuleSubstream(Substream, Visitor))
+      return std::move(E);
+  }
+
+  return Info;
+}
+
 Error YAMLOutputStyle::dumpFileHeaders() {
   if (opts::pdb2yaml::NoFileHeaders)
     return Error::success();
@@ -175,16 +289,24 @@ Error YAMLOutputStyle::dumpDbiStream() {
       if (opts::pdb2yaml::DbiModuleSourceFileInfo)
         DMI.SourceFiles = MI.SourceFiles;
 
+      auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
+          File.getMsfLayout(), File.getMsfBuffer(),
+          MI.Info.getModuleStreamIndex());
+
+      pdb::ModStream ModS(MI.Info, std::move(ModStreamData));
+      if (auto EC = ModS.reload())
+        return EC;
+
+      if (opts::pdb2yaml::DbiModuleSourceLineInfo) {
+        auto ExpectedInfo = getFileLineInfo(ModS);
+        if (!ExpectedInfo)
+          return ExpectedInfo.takeError();
+        DMI.FileLineInfo = *ExpectedInfo;
+      }
+
       if (opts::pdb2yaml::DbiModuleSyms &&
           MI.Info.getModuleStreamIndex() != kInvalidStreamIndex) {
         DMI.Modi.emplace();
-        auto ModStreamData = msf::MappedBlockStream::createIndexedStream(
-            File.getMsfLayout(), File.getMsfBuffer(),
-            MI.Info.getModuleStreamIndex());
-
-        pdb::ModStream ModS(MI.Info, std::move(ModStreamData));
-        if (auto EC = ModS.reload())
-          return EC;
 
         DMI.Modi->Signature = ModS.signature();
         bool HadError = false;
index db9868db4a7e114d6143ddeece6aed8747e370aa..263af776fa03f186c57ba78e5f09a5796f850d11 100644 (file)
@@ -19,6 +19,8 @@
 
 namespace llvm {
 namespace pdb {
+class ModStream;
+
 class YAMLOutputStyle : public OutputStyle {
 public:
   YAMLOutputStyle(PDBFile &File);
@@ -26,6 +28,9 @@ public:
   Error dump() override;
 
 private:
+  Expected<Optional<llvm::pdb::yaml::PdbSourceFileInfo>>
+  getFileLineInfo(const pdb::ModStream &ModS);
+
   Error dumpStringTable();
   Error dumpFileHeaders();
   Error dumpStreamMetadata();
index 172e29ac7f3292967eb2d20a5b2ef5ceea482a5f..e498c0187182cff25debd58cb36c5e3046c67631 100644 (file)
@@ -375,9 +375,15 @@ cl::opt<bool> DbiModuleSyms(
 cl::opt<bool> DbiModuleSourceFileInfo(
     "dbi-module-source-info",
     cl::desc(
-        "Dump DBI Module Source File Information (implies -dbi-module-info"),
+        "Dump DBI Module Source File Information (implies -dbi-module-info)"),
     cl::sub(PdbToYamlSubcommand), cl::init(false));
 
+cl::opt<bool>
+    DbiModuleSourceLineInfo("dbi-module-lines",
+                            cl::desc("Dump DBI Module Source Line Information "
+                                     "(implies -dbi-module-source-info)"),
+                            cl::sub(PdbToYamlSubcommand), cl::init(false));
+
 cl::opt<bool> TpiStream("tpi-stream",
                         cl::desc("Dump the TPI Stream (Stream 3)"),
                         cl::sub(PdbToYamlSubcommand), cl::init(false));
index 1bfba3518a59ba41fd73aec7714f4ed92a7252b9..d1af06fe3b4519426d9f5e5ef65ab36faf8b9751 100644 (file)
@@ -66,6 +66,7 @@ extern llvm::cl::opt<bool> DumpIpiRecords;
 extern llvm::cl::opt<bool> DumpIpiRecordBytes;
 extern llvm::cl::opt<bool> DumpModules;
 extern llvm::cl::opt<bool> DumpModuleFiles;
+extern llvm::cl::opt<bool> DumpModuleLines;
 extern llvm::cl::opt<bool> DumpModuleSyms;
 extern llvm::cl::opt<bool> DumpPublics;
 extern llvm::cl::opt<bool> DumpSectionContribs;
@@ -92,6 +93,7 @@ extern llvm::cl::opt<bool> DbiStream;
 extern llvm::cl::opt<bool> DbiModuleInfo;
 extern llvm::cl::opt<bool> DbiModuleSyms;
 extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
+extern llvm::cl::opt<bool> DbiModuleSourceLineInfo;
 extern llvm::cl::opt<bool> TpiStream;
 extern llvm::cl::opt<bool> IpiStream;
 extern llvm::cl::list<std::string> InputFilename;