[llvm] r304588 - [CodeView] Support CodeView subsections in any order.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 2 12:49:15 PDT 2017


Author: zturner
Date: Fri Jun  2 14:49:14 2017
New Revision: 304588

URL: http://llvm.org/viewvc/llvm-project?rev=304588&view=rev
Log:
[CodeView] Support CodeView subsections in any order.

Previously we would expect certain subsections to appear
in a certain order because some subsections would reference
other subsections, but in practice we need to support
arbitrary orderings since some object file and PDB file
producers generate them this way.  This also paves the
way for supporting Yaml <-> Object File conversion of
CodeView, since Object Files typically have quite a
large number of subsections in their debug info.

Differential Revision: https://reviews.llvm.org/D33807

Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
    llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
    llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
    llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
    llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
    llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
    llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
    llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
    llvm/trunk/test/DebugInfo/PDB/Inputs/simple-line-info.yaml
    llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
    llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
    llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h Fri Jun  2 14:49:14 2017
@@ -60,8 +60,8 @@ public:
   Error initialize(BinaryStreamReader Reader);
   Error initialize(BinaryStreamRef Stream);
 
-  Iterator begin() { return Checksums.begin(); }
-  Iterator end() { return Checksums.end(); }
+  Iterator begin() const { return Checksums.begin(); }
+  Iterator end() const { return Checksums.end(); }
 
   const FileChecksumArray &getArray() const { return Checksums; }
 

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h Fri Jun  2 14:49:14 2017
@@ -74,8 +74,13 @@ private:
 
 class DebugInlineeLinesSubsection final : public DebugSubsection {
 public:
+  struct Entry {
+    std::vector<support::ulittle32_t> ExtraFiles;
+    InlineeSourceLineHeader Header;
+  };
+
   DebugInlineeLinesSubsection(DebugChecksumsSubsection &Checksums,
-                              bool HasExtraFiles);
+                              bool HasExtraFiles = false);
 
   static bool classof(const DebugSubsection *S) {
     return S->kind() == DebugSubsectionKind::InlineeLines;
@@ -87,16 +92,18 @@ public:
   void addInlineSite(TypeIndex FuncId, StringRef FileName, uint32_t SourceLine);
   void addExtraFile(StringRef FileName);
 
+  bool hasExtraFiles() const { return HasExtraFiles; }
+  void setHasExtraFiles(bool Has) { HasExtraFiles = Has; }
+
+  std::vector<Entry>::const_iterator begin() const { return Entries.begin(); }
+  std::vector<Entry>::const_iterator end() const { return Entries.end(); }
+
 private:
   DebugChecksumsSubsection &Checksums;
 
   bool HasExtraFiles = false;
   uint32_t ExtraFileCount = 0;
 
-  struct Entry {
-    std::vector<support::ulittle32_t> ExtraFiles;
-    InlineeSourceLineHeader Header;
-  };
   std::vector<Entry> Entries;
 };
 }

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h Fri Jun  2 14:49:14 2017
@@ -49,15 +49,14 @@ private:
 
 class DebugSubsectionRecordBuilder {
 public:
-  DebugSubsectionRecordBuilder(DebugSubsectionKind Kind, DebugSubsection &Frag,
+  DebugSubsectionRecordBuilder(std::unique_ptr<DebugSubsection> Subsection,
                                CodeViewContainer Container);
   uint32_t calculateSerializedLength();
   Error commit(BinaryStreamWriter &Writer);
 
 private:
+  std::unique_ptr<DebugSubsection> Subsection;
   CodeViewContainer Container;
-  DebugSubsectionKind Kind;
-  DebugSubsection &Frag;
 };
 
 } // namespace codeview

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h Fri Jun  2 14:49:14 2017
@@ -49,11 +49,8 @@ public:
   void setObjFileName(StringRef Name);
   void addSymbol(codeview::CVSymbol Symbol);
 
-  void addC13Fragment(std::unique_ptr<codeview::DebugLinesSubsection> Lines);
-  void addC13Fragment(
-      std::unique_ptr<codeview::DebugInlineeLinesSubsection> Inlinees);
-  void setC13FileChecksums(
-      std::unique_ptr<codeview::DebugChecksumsSubsection> Checksums);
+  void
+  addDebugSubsection(std::unique_ptr<codeview::DebugSubsection> Subsection);
 
   uint16_t getStreamIndex() const;
   StringRef getModuleName() const { return ModuleName; }
@@ -83,10 +80,6 @@ private:
   std::vector<std::string> SourceFiles;
   std::vector<codeview::CVSymbol> Symbols;
 
-  std::unique_ptr<codeview::DebugChecksumsSubsection> ChecksumInfo;
-  std::vector<std::unique_ptr<codeview::DebugLinesSubsection>> LineInfo;
-  std::vector<std::unique_ptr<codeview::DebugInlineeLinesSubsection>> Inlinees;
-
   std::vector<std::unique_ptr<codeview::DebugSubsectionRecordBuilder>>
       C13Builders;
 

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=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h Fri Jun  2 14:49:14 2017
@@ -12,6 +12,7 @@
 
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -25,7 +26,7 @@ class PDBFile;
 class DbiModuleDescriptor;
 
 class ModuleDebugStreamRef {
-  typedef codeview::DebugSubsectionArray::Iterator LinesAndChecksumsIterator;
+  typedef codeview::DebugSubsectionArray::Iterator DebugSubsectionIterator;
 
 public:
   ModuleDebugStreamRef(const DbiModuleDescriptor &Module,
@@ -39,12 +40,15 @@ public:
   iterator_range<codeview::CVSymbolArray::Iterator>
   symbols(bool *HadError) const;
 
-  llvm::iterator_range<LinesAndChecksumsIterator> linesAndChecksums() const;
+  llvm::iterator_range<DebugSubsectionIterator> subsections() const;
 
-  bool hasLineInfo() const;
+  bool hasDebugSubsections() const;
 
   Error commit();
 
+  Expected<codeview::DebugChecksumsSubsectionRef>
+  findChecksumsSubsection() const;
+
 private:
   const DbiModuleDescriptor &Mod;
 
@@ -57,7 +61,7 @@ private:
   BinaryStreamRef C13LinesSubstream;
   BinaryStreamRef GlobalRefsSubstream;
 
-  codeview::DebugSubsectionArray LinesAndChecksums;
+  codeview::DebugSubsectionArray Subsections;
 };
 }
 }

Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/PDBStringTable.h Fri Jun  2 14:49:14 2017
@@ -45,6 +45,8 @@ public:
 
   FixedStreamArray<support::ulittle32_t> name_ids() const;
 
+  codeview::DebugStringTableSubsectionRef getStringTable() const;
+
 private:
   Error readHeader(BinaryStreamReader &Reader);
   Error readStrings(BinaryStreamReader &Reader);

Modified: llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/CodeViewYAMLDebugSections.h Fri Jun  2 14:49:14 2017
@@ -17,12 +17,20 @@
 
 #include "llvm/DebugInfo/CodeView/CodeView.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
 #include "llvm/ObjectYAML/YAML.h"
 
 namespace llvm {
+
+namespace codeview {
+class DebugStringTableSubsection;
+class DebugStringTableSubsectionRef;
+class DebugChecksumsSubsectionRef;
+}
 namespace CodeViewYAML {
+
 namespace detail {
-struct C13FragmentBase;
+struct YAMLSubsectionBase;
 }
 
 struct SourceLineEntry {
@@ -74,18 +82,24 @@ struct InlineeInfo {
   std::vector<InlineeSite> Sites;
 };
 
-struct SourceFileInfo {
-  std::vector<SourceFileChecksumEntry> FileChecksums;
-  std::vector<SourceLineInfo> LineFragments;
-  std::vector<InlineeInfo> Inlinees;
+struct YAMLDebugSubsection {
+  static Expected<YAMLDebugSubsection>
+  fromCodeViewSubection(const codeview::DebugStringTableSubsectionRef &Strings,
+                        const codeview::DebugChecksumsSubsectionRef &Checksums,
+                        const codeview::DebugSubsectionRecord &SS);
+
+  std::shared_ptr<detail::YAMLSubsectionBase> Subsection;
 };
 
-struct C13DebugSection {
-  std::vector<detail::C13FragmentBase> Fragments;
-};
+Expected<std::vector<std::unique_ptr<codeview::DebugSubsection>>>
+convertSubsectionList(ArrayRef<YAMLDebugSubsection> Subsections,
+                      codeview::DebugStringTableSubsection &Strings);
+
 } // namespace CodeViewYAML
 } // namespace llvm
 
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileInfo)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::YAMLDebugSubsection)
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::YAMLDebugSubsection)
 
 #endif

Modified: llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp Fri Jun  2 14:49:14 2017
@@ -72,7 +72,7 @@ Error DebugStringTableSubsection::commit
 uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
 
 uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
-  auto P = Strings.find(S);
-  assert(P != Strings.end());
-  return P->second;
+  auto Iter = Strings.find(S);
+  assert(Iter != Strings.end());
+  return Iter->second;
 }

Modified: llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp Fri Jun  2 14:49:14 2017
@@ -60,13 +60,13 @@ DebugSubsectionKind DebugSubsectionRecor
 BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
 
 DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
-    DebugSubsectionKind Kind, DebugSubsection &Frag,
-    CodeViewContainer Container)
-    : Container(Container), Kind(Kind), Frag(Frag) {}
+    std::unique_ptr<DebugSubsection> Subsection, CodeViewContainer Container)
+    : Subsection(std::move(Subsection)), Container(Container) {}
 
 uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
-  uint32_t Size = sizeof(DebugSubsectionHeader) +
-                  alignTo(Frag.calculateSerializedSize(), alignOf(Container));
+  uint32_t Size =
+      sizeof(DebugSubsectionHeader) +
+      alignTo(Subsection->calculateSerializedSize(), alignOf(Container));
   return Size;
 }
 
@@ -75,12 +75,12 @@ Error DebugSubsectionRecordBuilder::comm
          "Debug Subsection not properly aligned");
 
   DebugSubsectionHeader Header;
-  Header.Kind = uint32_t(Kind);
+  Header.Kind = uint32_t(Subsection->kind());
   Header.Length = calculateSerializedLength() - sizeof(DebugSubsectionHeader);
 
   if (auto EC = Writer.writeObject(Header))
     return EC;
-  if (auto EC = Frag.commit(Writer))
+  if (auto EC = Subsection->commit(Writer))
     return EC;
   if (auto EC = Writer.padToAlignment(alignOf(Container)))
     return EC;

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp Fri Jun  2 14:49:14 2017
@@ -174,42 +174,9 @@ Error DbiModuleDescriptorBuilder::commit
   return Error::success();
 }
 
-void DbiModuleDescriptorBuilder::addC13Fragment(
-    std::unique_ptr<DebugLinesSubsection> Lines) {
-  DebugLinesSubsection &Frag = *Lines;
-
-  // File Checksums have to come first, so push an empty entry on if this
-  // is the first.
-  if (C13Builders.empty())
-    C13Builders.push_back(nullptr);
-
-  this->LineInfo.push_back(std::move(Lines));
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+    std::unique_ptr<DebugSubsection> Subsection) {
+  assert(Subsection);
   C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
-      Frag.kind(), Frag, CodeViewContainer::Pdb));
-}
-
-void DbiModuleDescriptorBuilder::addC13Fragment(
-    std::unique_ptr<codeview::DebugInlineeLinesSubsection> Inlinees) {
-  DebugInlineeLinesSubsection &Frag = *Inlinees;
-
-  // File Checksums have to come first, so push an empty entry on if this
-  // is the first.
-  if (C13Builders.empty())
-    C13Builders.push_back(nullptr);
-
-  this->Inlinees.push_back(std::move(Inlinees));
-  C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
-      Frag.kind(), Frag, CodeViewContainer::Pdb));
-}
-
-void DbiModuleDescriptorBuilder::setC13FileChecksums(
-    std::unique_ptr<DebugChecksumsSubsection> Checksums) {
-  assert(!ChecksumInfo && "Can't have more than one checksum info!");
-
-  if (C13Builders.empty())
-    C13Builders.push_back(nullptr);
-
-  ChecksumInfo = std::move(Checksums);
-  C13Builders[0] = llvm::make_unique<DebugSubsectionRecordBuilder>(
-      ChecksumInfo->kind(), *ChecksumInfo, CodeViewContainer::Pdb);
+      std::move(Subsection), CodeViewContainer::Pdb));
 }

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=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp Fri Jun  2 14:49:14 2017
@@ -55,9 +55,9 @@ Error ModuleDebugStreamRef::reload() {
   if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
     return EC;
 
-  BinaryStreamReader LineReader(C13LinesSubstream);
-  if (auto EC =
-          LineReader.readArray(LinesAndChecksums, LineReader.bytesRemaining()))
+  BinaryStreamReader SubsectionsReader(C13LinesSubstream);
+  if (auto EC = SubsectionsReader.readArray(Subsections,
+                                            SubsectionsReader.bytesRemaining()))
     return EC;
 
   uint32_t GlobalRefsSize;
@@ -77,13 +77,27 @@ ModuleDebugStreamRef::symbols(bool *HadE
   return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
 }
 
-llvm::iterator_range<ModuleDebugStreamRef::LinesAndChecksumsIterator>
-ModuleDebugStreamRef::linesAndChecksums() const {
-  return make_range(LinesAndChecksums.begin(), LinesAndChecksums.end());
+llvm::iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
+ModuleDebugStreamRef::subsections() const {
+  return make_range(Subsections.begin(), Subsections.end());
 }
 
-bool ModuleDebugStreamRef::hasLineInfo() const {
+bool ModuleDebugStreamRef::hasDebugSubsections() const {
   return C13LinesSubstream.getLength() > 0;
 }
 
 Error ModuleDebugStreamRef::commit() { return Error::success(); }
+
+Expected<codeview::DebugChecksumsSubsectionRef>
+ModuleDebugStreamRef::findChecksumsSubsection() const {
+  for (const auto &SS : subsections()) {
+    if (SS.kind() != DebugSubsectionKind::FileChecksums)
+      continue;
+
+    codeview::DebugChecksumsSubsectionRef Result;
+    if (auto EC = Result.initialize(SS.getRecordData()))
+      return std::move(EC);
+    return Result;
+  }
+  return make_error<RawError>(raw_error_code::no_entry);
+}

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBStringTable.cpp Fri Jun  2 14:49:14 2017
@@ -56,6 +56,10 @@ Error PDBStringTable::readStrings(Binary
   return Error::success();
 }
 
+codeview::DebugStringTableSubsectionRef PDBStringTable::getStringTable() const {
+  return Strings;
+}
+
 Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
   const support::ulittle32_t *HashCount;
   if (auto EC = Reader.readObject(HashCount))

Modified: llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp Fri Jun  2 14:49:14 2017
@@ -17,6 +17,11 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
 #include "llvm/DebugInfo/CodeView/EnumTables.h"
 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
 
@@ -36,16 +41,80 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo
 LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
 
 LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false)
+LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
 LLVM_YAML_DECLARE_ENUM_TRAITS(FileChecksumKind)
 LLVM_YAML_DECLARE_BITSET_TRAITS(LineFlags)
 
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineEntry)
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceColumnEntry)
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceFileChecksumEntry)
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineInfo)
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::SourceLineBlock)
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeInfo)
-LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::InlineeSite)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineEntry)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceColumnEntry)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceFileChecksumEntry)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(SourceLineBlock)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(InlineeSite)
+
+namespace llvm {
+namespace CodeViewYAML {
+namespace detail {
+struct YAMLSubsectionBase {
+  explicit YAMLSubsectionBase(DebugSubsectionKind Kind) : Kind(Kind) {}
+  DebugSubsectionKind Kind;
+  virtual ~YAMLSubsectionBase() {}
+
+  virtual void map(IO &IO) = 0;
+  virtual std::unique_ptr<DebugSubsection>
+  toCodeViewSubsection(DebugStringTableSubsection *UseStrings,
+                       DebugChecksumsSubsection *UseChecksums) const = 0;
+};
+}
+}
+}
+
+namespace {
+struct YAMLChecksumsSubsection : public YAMLSubsectionBase {
+  YAMLChecksumsSubsection()
+      : YAMLSubsectionBase(DebugSubsectionKind::FileChecksums) {}
+
+  void map(IO &IO) override;
+  std::unique_ptr<DebugSubsection>
+  toCodeViewSubsection(DebugStringTableSubsection *Strings,
+                       DebugChecksumsSubsection *Checksums) const override;
+  static Expected<std::shared_ptr<YAMLChecksumsSubsection>>
+  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
+                         const DebugChecksumsSubsectionRef &FC);
+
+  std::vector<SourceFileChecksumEntry> Checksums;
+};
+
+struct YAMLLinesSubsection : public YAMLSubsectionBase {
+  YAMLLinesSubsection() : YAMLSubsectionBase(DebugSubsectionKind::Lines) {}
+
+  void map(IO &IO) override;
+  std::unique_ptr<DebugSubsection>
+  toCodeViewSubsection(DebugStringTableSubsection *Strings,
+                       DebugChecksumsSubsection *Checksums) const override;
+  static Expected<std::shared_ptr<YAMLLinesSubsection>>
+  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
+                         const DebugChecksumsSubsectionRef &Checksums,
+                         const DebugLinesSubsectionRef &Lines);
+
+  SourceLineInfo Lines;
+};
+
+struct YAMLInlineeLinesSubsection : public YAMLSubsectionBase {
+  YAMLInlineeLinesSubsection()
+      : YAMLSubsectionBase(DebugSubsectionKind::InlineeLines) {}
+
+  void map(IO &IO) override;
+  std::unique_ptr<DebugSubsection>
+  toCodeViewSubsection(DebugStringTableSubsection *Strings,
+                       DebugChecksumsSubsection *Checksums) const override;
+  static Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
+  fromCodeViewSubsection(const DebugStringTableSubsectionRef &Strings,
+                         const DebugChecksumsSubsectionRef &Checksums,
+                         const DebugInlineeLinesSubsectionRef &Lines);
+
+  InlineeInfo InlineeLines;
+};
+}
 
 void ScalarBitSetTraits<LineFlags>::bitset(IO &io, LineFlags &Flags) {
   io.bitSetCase(Flags, "HasColumnInfo", LF_HaveColumns);
@@ -99,21 +168,6 @@ void MappingTraits<SourceFileChecksumEnt
   IO.mapRequired("Checksum", Obj.ChecksumBytes);
 }
 
-void MappingTraits<SourceLineInfo>::mapping(IO &IO, SourceLineInfo &Obj) {
-  IO.mapRequired("CodeSize", Obj.CodeSize);
-
-  IO.mapRequired("Flags", Obj.Flags);
-  IO.mapRequired("RelocOffset", Obj.RelocOffset);
-  IO.mapRequired("RelocSegment", Obj.RelocSegment);
-  IO.mapRequired("Blocks", Obj.Blocks);
-}
-
-void MappingTraits<SourceFileInfo>::mapping(IO &IO, SourceFileInfo &Obj) {
-  IO.mapOptional("Checksums", Obj.FileChecksums);
-  IO.mapOptional("Lines", Obj.LineFragments);
-  IO.mapOptional("InlineeLines", Obj.Inlinees);
-}
-
 void MappingTraits<InlineeSite>::mapping(IO &IO, InlineeSite &Obj) {
   IO.mapRequired("FileName", Obj.FileName);
   IO.mapRequired("LineNum", Obj.SourceLineNum);
@@ -121,7 +175,310 @@ void MappingTraits<InlineeSite>::mapping
   IO.mapOptional("ExtraFiles", Obj.ExtraFiles);
 }
 
-void MappingTraits<InlineeInfo>::mapping(IO &IO, InlineeInfo &Obj) {
-  IO.mapRequired("HasExtraFiles", Obj.HasExtraFiles);
-  IO.mapRequired("Sites", Obj.Sites);
+void YAMLChecksumsSubsection::map(IO &IO) {
+  IO.mapTag("!FileChecksums", true);
+  IO.mapRequired("Checksums", Checksums);
+}
+
+void YAMLLinesSubsection::map(IO &IO) {
+  IO.mapTag("!Lines", true);
+  IO.mapRequired("CodeSize", Lines.CodeSize);
+
+  IO.mapRequired("Flags", Lines.Flags);
+  IO.mapRequired("RelocOffset", Lines.RelocOffset);
+  IO.mapRequired("RelocSegment", Lines.RelocSegment);
+  IO.mapRequired("Blocks", Lines.Blocks);
+}
+
+void YAMLInlineeLinesSubsection::map(IO &IO) {
+  IO.mapTag("!InlineeLines", true);
+  IO.mapRequired("HasExtraFiles", InlineeLines.HasExtraFiles);
+  IO.mapRequired("Sites", InlineeLines.Sites);
+}
+
+void MappingTraits<YAMLDebugSubsection>::mapping(
+    IO &IO, YAMLDebugSubsection &Subsection) {
+  if (!IO.outputting()) {
+    if (IO.mapTag("!FileChecksums")) {
+      auto SS = std::make_shared<YAMLChecksumsSubsection>();
+      Subsection.Subsection = SS;
+    } else if (IO.mapTag("!Lines")) {
+      Subsection.Subsection = std::make_shared<YAMLLinesSubsection>();
+    } else if (IO.mapTag("!InlineeLines")) {
+      Subsection.Subsection = std::make_shared<YAMLInlineeLinesSubsection>();
+    } else {
+      llvm_unreachable("Unexpected subsection tag!");
+    }
+  }
+  Subsection.Subsection->map(IO);
+}
+
+static Expected<const YAMLChecksumsSubsection &>
+findChecksums(ArrayRef<YAMLDebugSubsection> Subsections) {
+  for (const auto &SS : Subsections) {
+    if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums) {
+      return static_cast<const YAMLChecksumsSubsection &>(*SS.Subsection);
+    }
+  }
+  return make_error<CodeViewError>(cv_error_code::no_records);
+}
+
+std::unique_ptr<DebugSubsection> YAMLChecksumsSubsection::toCodeViewSubsection(
+    DebugStringTableSubsection *UseStrings,
+    DebugChecksumsSubsection *UseChecksums) const {
+  assert(UseStrings && !UseChecksums);
+  auto Result = llvm::make_unique<DebugChecksumsSubsection>(*UseStrings);
+  for (const auto &CS : Checksums) {
+    Result->addChecksum(CS.FileName, CS.Kind, CS.ChecksumBytes.Bytes);
+  }
+  return std::move(Result);
+}
+
+std::unique_ptr<DebugSubsection> YAMLLinesSubsection::toCodeViewSubsection(
+    DebugStringTableSubsection *UseStrings,
+    DebugChecksumsSubsection *UseChecksums) const {
+  assert(UseStrings && UseChecksums);
+  auto Result =
+      llvm::make_unique<DebugLinesSubsection>(*UseChecksums, *UseStrings);
+  Result->setCodeSize(Lines.CodeSize);
+  Result->setRelocationAddress(Lines.RelocSegment, Lines.RelocOffset);
+  Result->setFlags(Lines.Flags);
+  for (const auto &LC : Lines.Blocks) {
+    Result->createBlock(LC.FileName);
+    if (Result->hasColumnInfo()) {
+      for (const auto &Item : zip(LC.Lines, LC.Columns)) {
+        auto &L = std::get<0>(Item);
+        auto &C = std::get<1>(Item);
+        uint32_t LE = L.LineStart + L.EndDelta;
+        Result->addLineAndColumnInfo(L.Offset,
+                                     LineInfo(L.LineStart, LE, L.IsStatement),
+                                     C.StartColumn, C.EndColumn);
+      }
+    } else {
+      for (const auto &L : LC.Lines) {
+        uint32_t LE = L.LineStart + L.EndDelta;
+        Result->addLineInfo(L.Offset, LineInfo(L.LineStart, LE, L.IsStatement));
+      }
+    }
+  }
+  return Result;
+}
+
+std::unique_ptr<DebugSubsection>
+YAMLInlineeLinesSubsection::toCodeViewSubsection(
+    DebugStringTableSubsection *UseStrings,
+    DebugChecksumsSubsection *UseChecksums) const {
+  assert(UseChecksums);
+  auto Result = llvm::make_unique<DebugInlineeLinesSubsection>(
+      *UseChecksums, InlineeLines.HasExtraFiles);
+
+  for (const auto &Site : InlineeLines.Sites) {
+    Result->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
+                          Site.SourceLineNum);
+    if (!InlineeLines.HasExtraFiles)
+      continue;
+
+    for (auto EF : Site.ExtraFiles) {
+      Result->addExtraFile(EF);
+    }
+  }
+  return Result;
+}
+
+static Expected<SourceFileChecksumEntry>
+convertOneChecksum(const DebugStringTableSubsectionRef &Strings,
+                   const FileChecksumEntry &CS) {
+  auto ExpectedString = Strings.getString(CS.FileNameOffset);
+  if (!ExpectedString)
+    return ExpectedString.takeError();
+
+  SourceFileChecksumEntry Result;
+  Result.ChecksumBytes.Bytes = CS.Checksum;
+  Result.Kind = CS.Kind;
+  Result.FileName = *ExpectedString;
+  return Result;
+}
+
+static Expected<StringRef>
+getFileName(const DebugStringTableSubsectionRef &Strings,
+            const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID) {
+  auto Iter = Checksums.getArray().at(FileID);
+  if (Iter == Checksums.getArray().end())
+    return make_error<CodeViewError>(cv_error_code::no_records);
+  uint32_t Offset = Iter->FileNameOffset;
+  return Strings.getString(Offset);
+}
+
+Expected<std::shared_ptr<YAMLChecksumsSubsection>>
+YAMLChecksumsSubsection::fromCodeViewSubsection(
+    const DebugStringTableSubsectionRef &Strings,
+    const DebugChecksumsSubsectionRef &FC) {
+  auto Result = std::make_shared<YAMLChecksumsSubsection>();
+
+  for (const auto &CS : FC) {
+    auto ConvertedCS = convertOneChecksum(Strings, CS);
+    if (!ConvertedCS)
+      return ConvertedCS.takeError();
+    Result->Checksums.push_back(*ConvertedCS);
+  }
+  return Result;
+}
+
+Expected<std::shared_ptr<YAMLLinesSubsection>>
+YAMLLinesSubsection::fromCodeViewSubsection(
+    const DebugStringTableSubsectionRef &Strings,
+    const DebugChecksumsSubsectionRef &Checksums,
+    const DebugLinesSubsectionRef &Lines) {
+  auto Result = std::make_shared<YAMLLinesSubsection>();
+  Result->Lines.CodeSize = Lines.header()->CodeSize;
+  Result->Lines.RelocOffset = Lines.header()->RelocOffset;
+  Result->Lines.RelocSegment = Lines.header()->RelocSegment;
+  Result->Lines.Flags = static_cast<LineFlags>(uint16_t(Lines.header()->Flags));
+  for (const auto &L : Lines) {
+    SourceLineBlock Block;
+    auto EF = getFileName(Strings, Checksums, L.NameIndex);
+    if (!EF)
+      return EF.takeError();
+    Block.FileName = *EF;
+    if (Lines.hasColumnInfo()) {
+      for (const auto &C : L.Columns) {
+        SourceColumnEntry SCE;
+        SCE.EndColumn = C.EndColumn;
+        SCE.StartColumn = C.StartColumn;
+        Block.Columns.push_back(SCE);
+      }
+    }
+    for (const auto &LN : L.LineNumbers) {
+      SourceLineEntry SLE;
+      LineInfo LI(LN.Flags);
+      SLE.Offset = LN.Offset;
+      SLE.LineStart = LI.getStartLine();
+      SLE.EndDelta = LI.getLineDelta();
+      SLE.IsStatement = LI.isStatement();
+      Block.Lines.push_back(SLE);
+    }
+    Result->Lines.Blocks.push_back(Block);
+  }
+  return Result;
+}
+
+Expected<std::shared_ptr<YAMLInlineeLinesSubsection>>
+YAMLInlineeLinesSubsection::fromCodeViewSubsection(
+    const DebugStringTableSubsectionRef &Strings,
+    const DebugChecksumsSubsectionRef &Checksums,
+    const DebugInlineeLinesSubsectionRef &Lines) {
+  auto Result = std::make_shared<YAMLInlineeLinesSubsection>();
+
+  Result->InlineeLines.HasExtraFiles = Lines.hasExtraFiles();
+  for (const auto &IL : Lines) {
+    InlineeSite Site;
+    auto ExpF = getFileName(Strings, Checksums, IL.Header->FileID);
+    if (!ExpF)
+      return ExpF.takeError();
+    Site.FileName = *ExpF;
+    Site.Inlinee = IL.Header->Inlinee.getIndex();
+    Site.SourceLineNum = IL.Header->SourceLineNum;
+    if (Lines.hasExtraFiles()) {
+      for (const auto EF : IL.ExtraFiles) {
+        auto ExpF2 = getFileName(Strings, Checksums, EF);
+        if (!ExpF2)
+          return ExpF2.takeError();
+        Site.ExtraFiles.push_back(*ExpF2);
+      }
+    }
+    Result->InlineeLines.Sites.push_back(Site);
+  }
+  return Result;
+}
+
+Expected<std::vector<std::unique_ptr<DebugSubsection>>>
+llvm::CodeViewYAML::convertSubsectionList(
+    ArrayRef<YAMLDebugSubsection> Subsections,
+    DebugStringTableSubsection &Strings) {
+  std::vector<std::unique_ptr<DebugSubsection>> Result;
+  if (Subsections.empty())
+    return Result;
+
+  auto Checksums = findChecksums(Subsections);
+  if (!Checksums)
+    return Checksums.takeError();
+  auto ChecksumsBase = Checksums->toCodeViewSubsection(&Strings, nullptr);
+  DebugChecksumsSubsection &CS =
+      llvm::cast<DebugChecksumsSubsection>(*ChecksumsBase);
+  for (const auto &SS : Subsections) {
+    // We've already converted the checksums subsection, don't do it
+    // twice.
+    std::unique_ptr<DebugSubsection> CVS;
+    if (SS.Subsection->Kind == DebugSubsectionKind::FileChecksums)
+      CVS = std::move(ChecksumsBase);
+    else
+      CVS = SS.Subsection->toCodeViewSubsection(&Strings, &CS);
+    Result.push_back(std::move(CVS));
+  }
+  return std::move(Result);
+}
+
+namespace {
+struct SubsectionConversionVisitor : public DebugSubsectionVisitor {
+  explicit SubsectionConversionVisitor(
+      const DebugStringTableSubsectionRef &Strings,
+      const DebugChecksumsSubsectionRef &Checksums)
+      : Strings(Strings), Checksums(Checksums) {}
+
+  Error visitUnknown(DebugUnknownSubsectionRef &Unknown) override;
+  Error visitLines(DebugLinesSubsectionRef &Lines) override;
+  Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums) override;
+  Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees) override;
+
+  YAMLDebugSubsection Subsection;
+
+private:
+  const DebugStringTableSubsectionRef &Strings;
+  const DebugChecksumsSubsectionRef &Checksums;
+};
+
+Error SubsectionConversionVisitor::visitUnknown(
+    DebugUnknownSubsectionRef &Unknown) {
+  return make_error<CodeViewError>(cv_error_code::operation_unsupported);
+}
+
+Error SubsectionConversionVisitor::visitLines(DebugLinesSubsectionRef &Lines) {
+  auto Result =
+      YAMLLinesSubsection::fromCodeViewSubsection(Strings, Checksums, Lines);
+  if (!Result)
+    return Result.takeError();
+  Subsection.Subsection = *Result;
+  return Error::success();
+}
+
+Error SubsectionConversionVisitor::visitFileChecksums(
+    DebugChecksumsSubsectionRef &Checksums) {
+  auto Result =
+      YAMLChecksumsSubsection::fromCodeViewSubsection(Strings, Checksums);
+  if (!Result)
+    return Result.takeError();
+  Subsection.Subsection = *Result;
+  return Error::success();
+}
+
+Error SubsectionConversionVisitor::visitInlineeLines(
+    DebugInlineeLinesSubsectionRef &Inlinees) {
+  auto Result = YAMLInlineeLinesSubsection::fromCodeViewSubsection(
+      Strings, Checksums, Inlinees);
+  if (!Result)
+    return Result.takeError();
+  Subsection.Subsection = *Result;
+  return Error::success();
+}
+}
+
+Expected<YAMLDebugSubsection> YAMLDebugSubsection::fromCodeViewSubection(
+    const DebugStringTableSubsectionRef &Strings,
+    const DebugChecksumsSubsectionRef &Checksums,
+    const DebugSubsectionRecord &SS) {
+  SubsectionConversionVisitor V(Strings, Checksums);
+  if (auto EC = visitDebugSubsection(SS, V))
+    return std::move(EC);
+
+  return V.Subsection;
 }

Modified: llvm/trunk/test/DebugInfo/PDB/Inputs/simple-line-info.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/Inputs/simple-line-info.yaml?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/Inputs/simple-line-info.yaml (original)
+++ llvm/trunk/test/DebugInfo/PDB/Inputs/simple-line-info.yaml Fri Jun  2 14:49:14 2017
@@ -5,39 +5,40 @@ DbiStream:
       ObjFile:         'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'
       SourceFiles:
         - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
-      LineInfo:
-        Checksums:
-          - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
-            Kind:            MD5
-            Checksum:        A0A5BD0D3ECD93FC29D19DE826FBF4BC
-          - FileName:        'f:\dd\externalapis\windows\10\sdk\inc\winerror.h'
-            Kind:            MD5
-            Checksum:        1154D69F5B2650196E1FC34F4134E56B
-        Lines:
-          - CodeSize:        10
-            Flags:           [  ]
-            RelocOffset:     16
-            RelocSegment:    1
-            Blocks:
-              - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
-                Lines:
-                  - Offset:          0
-                    LineStart:       5
-                    IsStatement:     true
-                    EndDelta:        0
-                  - Offset:          3
-                    LineStart:       6
-                    IsStatement:     true
-                    EndDelta:        0
-                  - Offset:          8
-                    LineStart:       7
-                    IsStatement:     true
-                    EndDelta:        0
-                Columns:
-        InlineeLines:    
-          - HasExtraFiles:   false
-            Sites:           
-              - FileName:        'f:\dd\externalapis\windows\10\sdk\inc\winerror.h'
-                LineNum:         26950
-                Inlinee:         22767
+      Subsections:
+        - !FileChecksums
+          Checksums:
+            - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
+              Kind:            MD5
+              Checksum:        A0A5BD0D3ECD93FC29D19DE826FBF4BC
+            - FileName:        'f:\dd\externalapis\windows\10\sdk\inc\winerror.h'
+              Kind:            MD5
+              Checksum:        1154D69F5B2650196E1FC34F4134E56B
+        - !Lines
+          CodeSize:        10
+          Flags:           [  ]
+          RelocOffset:     16
+          RelocSegment:    1
+          Blocks:
+            - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
+              Lines:
+                - Offset:          0
+                  LineStart:       5
+                  IsStatement:     true
+                  EndDelta:        0
+                - Offset:          3
+                  LineStart:       6
+                  IsStatement:     true
+                  EndDelta:        0
+                - Offset:          8
+                  LineStart:       7
+                  IsStatement:     true
+                  EndDelta:        0
+              Columns:
+        - !InlineeLines
+          HasExtraFiles:   false
+          Sites:           
+            - FileName:        'f:\dd\externalapis\windows\10\sdk\inc\winerror.h'
+              LineNum:         26950
+              Inlinee:         22767
 ...

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-yaml-lineinfo.test Fri Jun  2 14:49:14 2017
@@ -28,12 +28,8 @@ YAML:   - Module:          'd:\src\llvm\
 YAML:     ObjFile:         'd:\src\llvm\test\DebugInfo\PDB\Inputs\empty.obj'
 YAML:     SourceFiles:
 YAML:       - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
-YAML:     LineInfo:
-YAML:       Checksums:
-YAML:         - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
-YAML:           Kind:            MD5
-YAML:           Checksum:        A0A5BD0D3ECD93FC29D19DE826FBF4BC
-YAML:       Lines:
+YAML:     Subsections:
+YAML:       - !Lines
 YAML:         CodeSize:        10
 YAML:         Flags:           [  ]
 YAML:         RelocOffset:     16
@@ -54,6 +50,11 @@ YAML:                 LineStart:       7
 YAML:                 IsStatement:     true
 YAML:                 EndDelta:        0
 YAML:             Columns:
+YAML:       - !FileChecksums
+YAML:         Checksums:
+YAML:           - FileName:        'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
+YAML:             Kind:            MD5
+YAML:             Checksum:        A0A5BD0D3ECD93FC29D19DE826FBF4BC
 YAML:  - Module:          '* Linker *'
 YAML:    ObjFile:         ''
 YAML: ...
\ No newline at end of file

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Fri Jun  2 14:49:14 2017
@@ -831,8 +831,7 @@ Error LLVMOutputStyle::dumpDbiStream() {
             return ExpectedTypes.takeError();
           auto &IpiItems = *ExpectedTypes;
           C13RawVisitor V(P, File, IpiItems);
-          if (auto EC =
-                  codeview::visitDebugSubsections(ModS.linesAndChecksums(), V))
+          if (auto EC = codeview::visitDebugSubsections(ModS.subsections(), V))
             return EC;
         }
       }

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.cpp Fri Jun  2 14:49:14 2017
@@ -12,6 +12,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
 #include "llvm/DebugInfo/CodeView/TypeSerializer.h"
@@ -21,6 +22,7 @@
 #include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
 #include "llvm/DebugInfo/PDB/PDBExtras.h"
 #include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
 #include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
 
 using namespace llvm;
@@ -220,6 +222,6 @@ void MappingTraits<PdbDbiModuleInfo>::ma
   IO.mapRequired("Module", Obj.Mod);
   IO.mapOptional("ObjFile", Obj.Obj, Obj.Mod);
   IO.mapOptional("SourceFiles", Obj.SourceFiles);
-  IO.mapOptional("LineInfo", Obj.FileLineInfo);
+  IO.mapOptional("Subsections", Obj.Subsections);
   IO.mapOptional("Modi", Obj.Modi);
 }

Modified: llvm/trunk/tools/llvm-pdbdump/PdbYaml.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PdbYaml.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PdbYaml.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PdbYaml.h Fri Jun  2 14:49:14 2017
@@ -28,6 +28,9 @@
 #include <vector>
 
 namespace llvm {
+namespace codeview {
+class DebugStringTableSubsection;
+}
 namespace pdb {
 
 namespace yaml {
@@ -68,7 +71,7 @@ struct PdbDbiModuleInfo {
   StringRef Obj;
   StringRef Mod;
   std::vector<StringRef> SourceFiles;
-  Optional<CodeViewYAML::SourceFileInfo> FileLineInfo;
+  std::vector<CodeViewYAML::YAMLDebugSubsection> Subsections;
   Optional<PdbModiStream> Modi;
 };
 

Modified: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.cpp Fri Jun  2 14:49:14 2017
@@ -101,117 +101,6 @@ Error YAMLOutputStyle::dump() {
   return Error::success();
 }
 
-namespace {
-class C13YamlVisitor : public C13DebugFragmentVisitor {
-public:
-  C13YamlVisitor(CodeViewYAML::SourceFileInfo &Info, PDBFile &F)
-      : C13DebugFragmentVisitor(F), Info(Info) {}
-
-  Error handleFileChecksums() override {
-    for (const auto &C : *Checksums) {
-      CodeViewYAML::SourceFileChecksumEntry Entry;
-      if (auto Result = getNameFromStringTable(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 handleLines() override {
-    for (const auto &LF : Lines) {
-      Info.LineFragments.emplace_back();
-      auto &Fragment = Info.LineFragments.back();
-
-      Fragment.CodeSize = LF.header()->CodeSize;
-      Fragment.Flags =
-          static_cast<codeview::LineFlags>(uint16_t(LF.header()->Flags));
-      Fragment.RelocOffset = LF.header()->RelocOffset;
-      Fragment.RelocSegment = LF.header()->RelocSegment;
-
-      for (const auto &L : LF) {
-        Fragment.Blocks.emplace_back();
-        auto &Block = Fragment.Blocks.back();
-
-        if (auto Result = getNameFromChecksumsBuffer(L.NameIndex))
-          Block.FileName = *Result;
-        else
-          return Result.takeError();
-
-        for (const auto &N : L.LineNumbers) {
-          CodeViewYAML::SourceLineEntry Line;
-          Line.Offset = N.Offset;
-          codeview::LineInfo LI(N.Flags);
-          Line.LineStart = LI.getStartLine();
-          Line.EndDelta = LI.getLineDelta();
-          Line.IsStatement = LI.isStatement();
-          Block.Lines.push_back(Line);
-        }
-
-        if (LF.hasColumnInfo()) {
-          for (const auto &C : L.Columns) {
-            CodeViewYAML::SourceColumnEntry Column;
-            Column.StartColumn = C.StartColumn;
-            Column.EndColumn = C.EndColumn;
-            Block.Columns.push_back(Column);
-          }
-        }
-      }
-    }
-    return Error::success();
-  }
-
-  Error handleInlineeLines() override {
-    for (const auto &ILF : InlineeLines) {
-      Info.Inlinees.emplace_back();
-      auto &Inlinee = Info.Inlinees.back();
-
-      Inlinee.HasExtraFiles = ILF.hasExtraFiles();
-      for (const auto &IL : ILF) {
-        Inlinee.Sites.emplace_back();
-        auto &Site = Inlinee.Sites.back();
-        if (auto Result = getNameFromChecksumsBuffer(IL.Header->FileID))
-          Site.FileName = *Result;
-        else
-          return Result.takeError();
-
-        Site.Inlinee = IL.Header->Inlinee.getIndex();
-        Site.SourceLineNum = IL.Header->SourceLineNum;
-        if (ILF.hasExtraFiles()) {
-          for (const auto &EF : IL.ExtraFiles) {
-            if (auto Result = getNameFromChecksumsBuffer(EF))
-              Site.ExtraFiles.push_back(*Result);
-            else
-              return Result.takeError();
-          }
-        }
-      }
-    }
-    return Error::success();
-  }
-
-private:
-  CodeViewYAML::SourceFileInfo &Info;
-};
-}
-
-Expected<Optional<CodeViewYAML::SourceFileInfo>>
-YAMLOutputStyle::getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS) {
-  if (!ModS.hasLineInfo())
-    return None;
-
-  CodeViewYAML::SourceFileInfo Info;
-  C13YamlVisitor Visitor(Info, File);
-  if (auto EC =
-          codeview::visitDebugSubsections(ModS.linesAndChecksums(), Visitor))
-    return std::move(EC);
-
-  return Info;
-}
 
 Error YAMLOutputStyle::dumpFileHeaders() {
   if (opts::pdb2yaml::NoFileHeaders)
@@ -236,14 +125,17 @@ Error YAMLOutputStyle::dumpFileHeaders()
 }
 
 Error YAMLOutputStyle::dumpStringTable() {
-  if (!opts::pdb2yaml::StringTable)
+  bool RequiresStringTable = opts::pdb2yaml::DbiModuleSourceFileInfo ||
+                             opts::pdb2yaml::DbiModuleSourceLineInfo;
+  bool RequestedStringTable = opts::pdb2yaml::StringTable;
+  if (!RequiresStringTable && !RequestedStringTable)
     return Error::success();
 
-  Obj.StringTable.emplace();
   auto ExpectedST = File.getStringTable();
   if (!ExpectedST)
     return ExpectedST.takeError();
 
+  Obj.StringTable.emplace();
   const auto &ST = ExpectedST.get();
   for (auto ID : ST.name_ids()) {
     auto S = ST.getStringForID(ID);
@@ -343,11 +235,23 @@ Error YAMLOutputStyle::dumpDbiStream() {
       if (auto EC = ModS.reload())
         return EC;
 
-      if (opts::pdb2yaml::DbiModuleSourceLineInfo) {
-        auto ExpectedInfo = getFileLineInfo(ModS);
-        if (!ExpectedInfo)
-          return ExpectedInfo.takeError();
-        DMI.FileLineInfo = *ExpectedInfo;
+      auto ExpectedST = File.getStringTable();
+      if (!ExpectedST)
+        return ExpectedST.takeError();
+      if (opts::pdb2yaml::DbiModuleSourceLineInfo &&
+          ModS.hasDebugSubsections()) {
+        auto ExpectedChecksums = ModS.findChecksumsSubsection();
+        if (!ExpectedChecksums)
+          return ExpectedChecksums.takeError();
+
+        for (const auto &SS : ModS.subsections()) {
+          auto Converted =
+              CodeViewYAML::YAMLDebugSubsection::fromCodeViewSubection(
+                  ExpectedST->getStringTable(), *ExpectedChecksums, SS);
+          if (!Converted)
+            return Converted.takeError();
+          DMI.Subsections.push_back(*Converted);
+        }
       }
 
       if (opts::pdb2yaml::DbiModuleSyms) {

Modified: llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/YAMLOutputStyle.h Fri Jun  2 14:49:14 2017
@@ -27,9 +27,6 @@ public:
   Error dump() override;
 
 private:
-  Expected<Optional<CodeViewYAML::SourceFileInfo>>
-  getFileLineInfo(const pdb::ModuleDebugStreamRef &ModS);
-
   Error dumpStringTable();
   Error dumpFileHeaders();
   Error dumpStreamMetadata();

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=304588&r1=304587&r2=304588&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Fri Jun  2 14:49:14 2017
@@ -476,7 +476,6 @@ static void yamlToPdb(StringRef Path) {
   std::unique_ptr<MemoryBuffer> &Buffer = ErrorOrBuffer.get();
 
   llvm::yaml::Input In(Buffer->getBuffer());
-  In.setContext(&Allocator);
   pdb::yaml::PdbObject YamlObj(Allocator);
   In >> YamlObj;
 
@@ -540,64 +539,11 @@ static void yamlToPdb(StringRef Path) {
             Symbol.toCodeViewSymbol(Allocator, CodeViewContainer::Pdb));
       }
     }
-    if (MI.FileLineInfo.hasValue()) {
-      const auto &FLI = *MI.FileLineInfo;
 
-      // File Checksums must be emitted before line information, because line
-      // info records use offsets into the checksum buffer to reference a file's
-      // source file name.
-      auto Checksums = llvm::make_unique<DebugChecksumsSubsection>(Strings);
-      auto &ChecksumRef = *Checksums;
-      if (!FLI.FileChecksums.empty()) {
-        for (auto &FC : FLI.FileChecksums)
-          Checksums->addChecksum(FC.FileName, FC.Kind, FC.ChecksumBytes.Bytes);
-      }
-      ModiBuilder.setC13FileChecksums(std::move(Checksums));
-
-      for (const auto &Fragment : FLI.LineFragments) {
-        auto Lines =
-            llvm::make_unique<DebugLinesSubsection>(ChecksumRef, Strings);
-        Lines->setCodeSize(Fragment.CodeSize);
-        Lines->setRelocationAddress(Fragment.RelocSegment,
-                                    Fragment.RelocOffset);
-        Lines->setFlags(Fragment.Flags);
-        for (const auto &LC : Fragment.Blocks) {
-          Lines->createBlock(LC.FileName);
-          if (Lines->hasColumnInfo()) {
-            for (const auto &Item : zip(LC.Lines, LC.Columns)) {
-              auto &L = std::get<0>(Item);
-              auto &C = std::get<1>(Item);
-              uint32_t LE = L.LineStart + L.EndDelta;
-              Lines->addLineAndColumnInfo(
-                  L.Offset, LineInfo(L.LineStart, LE, L.IsStatement),
-                  C.StartColumn, C.EndColumn);
-            }
-          } else {
-            for (const auto &L : LC.Lines) {
-              uint32_t LE = L.LineStart + L.EndDelta;
-              Lines->addLineInfo(L.Offset,
-                                 LineInfo(L.LineStart, LE, L.IsStatement));
-            }
-          }
-        }
-        ModiBuilder.addC13Fragment(std::move(Lines));
-      }
-
-      for (const auto &Inlinee : FLI.Inlinees) {
-        auto Inlinees = llvm::make_unique<DebugInlineeLinesSubsection>(
-            ChecksumRef, Inlinee.HasExtraFiles);
-        for (const auto &Site : Inlinee.Sites) {
-          Inlinees->addInlineSite(TypeIndex(Site.Inlinee), Site.FileName,
-                                  Site.SourceLineNum);
-          if (!Inlinee.HasExtraFiles)
-            continue;
-
-          for (auto EF : Site.ExtraFiles) {
-            Inlinees->addExtraFile(EF);
-          }
-        }
-        ModiBuilder.addC13Fragment(std::move(Inlinees));
-      }
+    auto CodeViewSubsections =
+        ExitOnErr(CodeViewYAML::convertSubsectionList(MI.Subsections, Strings));
+    for (auto &SS : CodeViewSubsections) {
+      ModiBuilder.addDebugSubsection(std::move(SS));
     }
   }
 




More information about the llvm-commits mailing list