//===- DumpOutputStyle.cpp ------------------------------------ *- C++ --*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DumpOutputStyle.h"

#include "FormatUtil.h"
#include "MinimalSymbolDumper.h"
#include "MinimalTypeDumper.h"
#include "StreamUtil.h"
#include "llvm-pdbutil.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.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/DebugSymbolsSubsection.h"
#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/EnumTables.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"

#include <unordered_map>

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;

DumpOutputStyle::DumpOutputStyle(PDBFile &File)
    : File(File), P(2, false, outs()) {}

Error DumpOutputStyle::dump() {
  if (opts::dump::DumpSummary) {
    if (auto EC = dumpFileSummary())
      return EC;
    P.NewLine();
  }

  if (opts::dump::DumpStreams) {
    if (auto EC = dumpStreamSummary())
      return EC;
    P.NewLine();
  }

  if (opts::dump::DumpStringTable) {
    if (auto EC = dumpStringTable())
      return EC;
    P.NewLine();
  }

  if (opts::dump::DumpModules) {
    if (auto EC = dumpModules())
      return EC;
  }

  if (opts::dump::DumpModuleFiles) {
    if (auto EC = dumpModuleFiles())
      return EC;
  }

  if (opts::dump::DumpLines) {
    if (auto EC = dumpLines())
      return EC;
  }

  if (opts::dump::DumpInlineeLines) {
    if (auto EC = dumpInlineeLines())
      return EC;
  }

  if (opts::dump::DumpXmi) {
    if (auto EC = dumpXmi())
      return EC;
  }

  if (opts::dump::DumpXme) {
    if (auto EC = dumpXme())
      return EC;
  }

  if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
      opts::dump::DumpTypeExtras) {
    if (auto EC = dumpTpiStream(StreamTPI))
      return EC;
  }

  if (opts::dump::DumpIds || !opts::dump::DumpIdIndex.empty() ||
      opts::dump::DumpIdExtras) {
    if (auto EC = dumpTpiStream(StreamIPI))
      return EC;
  }

  if (opts::dump::DumpPublics) {
    if (auto EC = dumpPublics())
      return EC;
  }

  if (opts::dump::DumpSymbols) {
    if (auto EC = dumpModuleSyms())
      return EC;
  }

  if (opts::dump::DumpSectionContribs) {
    if (auto EC = dumpSectionContribs())
      return EC;
  }

  if (opts::dump::DumpSectionMap) {
    if (auto EC = dumpSectionMap())
      return EC;
  }

  return Error::success();
}

static void printHeader(LinePrinter &P, const Twine &S) {
  P.NewLine();
  P.formatLine("{0,=60}", S);
  P.formatLine("{0}", fmt_repeat('=', 60));
}

Error DumpOutputStyle::dumpFileSummary() {
  printHeader(P, "Summary");

  ExitOnError Err("Invalid PDB Format");

  AutoIndent Indent(P);
  P.formatLine("Block Size: {0}", File.getBlockSize());
  P.formatLine("Number of blocks: {0}", File.getBlockCount());
  P.formatLine("Number of streams: {0}", File.getNumStreams());

  auto &PS = Err(File.getPDBInfoStream());
  P.formatLine("Signature: {0}", PS.getSignature());
  P.formatLine("Age: {0}", PS.getAge());
  P.formatLine("GUID: {0}", fmt_guid(PS.getGuid().Guid));
  P.formatLine("Features: {0:x+}", static_cast<uint32_t>(PS.getFeatures()));
  P.formatLine("Has Debug Info: {0}", File.hasPDBDbiStream());
  P.formatLine("Has Types: {0}", File.hasPDBTpiStream());
  P.formatLine("Has IDs: {0}", File.hasPDBIpiStream());
  P.formatLine("Has Globals: {0}", File.hasPDBGlobalsStream());
  P.formatLine("Has Publics: {0}", File.hasPDBPublicsStream());
  if (File.hasPDBDbiStream()) {
    auto &DBI = Err(File.getPDBDbiStream());
    P.formatLine("Is incrementally linked: {0}", DBI.isIncrementallyLinked());
    P.formatLine("Has conflicting types: {0}", DBI.hasCTypes());
    P.formatLine("Is stripped: {0}", DBI.isStripped());
  }

  return Error::success();
}

Error DumpOutputStyle::dumpStreamSummary() {
  printHeader(P, "Streams");

  if (StreamPurposes.empty())
    discoverStreamPurposes(File, StreamPurposes);

  AutoIndent Indent(P);
  uint32_t StreamCount = File.getNumStreams();

  for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
    P.formatLine(
        "Stream {0}: [{1}] ({2} bytes)",
        fmt_align(StreamIdx, AlignStyle::Right, NumDigits(StreamCount)),
        StreamPurposes[StreamIdx], File.getStreamByteSize(StreamIdx));
    if (opts::dump::DumpStreamBlocks) {
      auto Blocks = File.getStreamBlockList(StreamIdx);
      std::vector<uint32_t> BV(Blocks.begin(), Blocks.end());
      P.formatLine("       {0}  Blocks: [{1}]",
                   fmt_repeat(' ', NumDigits(StreamCount)),
                   make_range(BV.begin(), BV.end()));
    }
  }

  return Error::success();
}

static Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
                                                           uint32_t Index) {
  ExitOnError Err("Unexpected error");

  auto &Dbi = Err(File.getPDBDbiStream());
  const auto &Modules = Dbi.modules();
  auto Modi = Modules.getModuleDescriptor(Index);

  uint16_t ModiStream = Modi.getModuleStreamIndex();
  if (ModiStream == kInvalidStreamIndex)
    return make_error<RawError>(raw_error_code::no_stream,
                                "Module stream not present");

  auto ModStreamData = MappedBlockStream::createIndexedStream(
      File.getMsfLayout(), File.getMsfBuffer(), ModiStream,
      File.getAllocator());

  ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
  if (auto EC = ModS.reload())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Invalid module stream");

  return std::move(ModS);
}

static std::string formatChecksumKind(FileChecksumKind Kind) {
  switch (Kind) {
    RETURN_CASE(FileChecksumKind, None, "None");
    RETURN_CASE(FileChecksumKind, MD5, "MD5");
    RETURN_CASE(FileChecksumKind, SHA1, "SHA-1");
    RETURN_CASE(FileChecksumKind, SHA256, "SHA-256");
  }
  return formatUnknownEnum(Kind);
}

namespace {
class StringsAndChecksumsPrinter {
  const DebugStringTableSubsectionRef &extractStringTable(PDBFile &File) {
    ExitOnError Err("Unexpected error processing modules");
    return Err(File.getStringTable()).getStringTable();
  }

  template <typename... Args>
  void formatInternal(LinePrinter &Printer, bool Append,
                      Args &&... args) const {
    if (Append)
      Printer.format(std::forward<Args>(args)...);
    else
      Printer.formatLine(std::forward<Args>(args)...);
  }

public:
  StringsAndChecksumsPrinter(PDBFile &File, uint32_t Modi)
      : Records(extractStringTable(File)) {
    auto MDS = getModuleDebugStream(File, Modi);
    if (!MDS) {
      consumeError(MDS.takeError());
      return;
    }

    DebugStream = llvm::make_unique<ModuleDebugStreamRef>(std::move(*MDS));
    Records.initialize(MDS->subsections());
    if (Records.hasChecksums()) {
      for (const auto &Entry : Records.checksums()) {
        auto S = Records.strings().getString(Entry.FileNameOffset);
        if (!S)
          continue;
        ChecksumsByFile[*S] = Entry;
      }
    }
  }

  Expected<StringRef> getNameFromStringTable(uint32_t Offset) const {
    return Records.strings().getString(Offset);
  }

  void formatFromFileName(LinePrinter &Printer, StringRef File,
                          bool Append = false) const {
    auto FC = ChecksumsByFile.find(File);
    if (FC == ChecksumsByFile.end()) {
      formatInternal(Printer, Append, "- (no checksum) {0}", File);
      return;
    }

    formatInternal(Printer, Append, "- ({0}: {1}) {2}",
                   formatChecksumKind(FC->getValue().Kind),
                   toHex(FC->getValue().Checksum), File);
  }

  void formatFromChecksumsOffset(LinePrinter &Printer, uint32_t Offset,
                                 bool Append = false) const {
    if (!Records.hasChecksums()) {
      formatInternal(Printer, Append, "(unknown file name offset {0})", Offset);
      return;
    }

    auto Iter = Records.checksums().getArray().at(Offset);
    if (Iter == Records.checksums().getArray().end()) {
      formatInternal(Printer, Append, "(unknown file name offset {0})", Offset);
      return;
    }

    uint32_t FO = Iter->FileNameOffset;
    auto ExpectedFile = getNameFromStringTable(FO);
    if (!ExpectedFile) {
      formatInternal(Printer, Append, "(unknown file name offset {0})", Offset);
      consumeError(ExpectedFile.takeError());
      return;
    }
    if (Iter->Kind == FileChecksumKind::None) {
      formatInternal(Printer, Append, "{0} (no checksum)", *ExpectedFile);
    } else {
      formatInternal(Printer, Append, "{0} ({1}: {2})", *ExpectedFile,
                     formatChecksumKind(Iter->Kind), toHex(Iter->Checksum));
    }
  }

  std::unique_ptr<ModuleDebugStreamRef> DebugStream;
  StringsAndChecksumsRef Records;
  StringMap<FileChecksumEntry> ChecksumsByFile;
};
} // namespace

template <typename CallbackT>
static void iterateModules(PDBFile &File, LinePrinter &P, uint32_t IndentLevel,
                           CallbackT Callback) {
  AutoIndent Indent(P);
  if (!File.hasPDBDbiStream()) {
    P.formatLine("DBI Stream not present");
    return;
  }

  ExitOnError Err("Unexpected error processing modules");

  auto &Stream = Err(File.getPDBDbiStream());

  const DbiModuleList &Modules = Stream.modules();
  uint32_t Count = Modules.getModuleCount();
  uint32_t Digits = NumDigits(Count);
  for (uint32_t I = 0; I < Count; ++I) {
    auto Modi = Modules.getModuleDescriptor(I);
    P.formatLine("Mod {0:4} | `{1}`: ", fmt_align(I, AlignStyle::Right, Digits),
                 Modi.getModuleName());

    StringsAndChecksumsPrinter Strings(File, I);
    AutoIndent Indent2(P, IndentLevel);
    Callback(I, Strings);
  }
}

template <typename SubsectionT>
static void iterateModuleSubsections(
    PDBFile &File, LinePrinter &P, uint32_t IndentLevel,
    llvm::function_ref<void(uint32_t, StringsAndChecksumsPrinter &,
                            SubsectionT &)>
        Callback) {

  iterateModules(
      File, P, IndentLevel,
      [&File, &Callback](uint32_t Modi, StringsAndChecksumsPrinter &Strings) {
        auto MDS = getModuleDebugStream(File, Modi);
        if (!MDS) {
          consumeError(MDS.takeError());
          return;
        }

        for (const auto &SS : MDS->subsections()) {
          SubsectionT Subsection;

          if (SS.kind() != Subsection.kind())
            continue;

          BinaryStreamReader Reader(SS.getRecordData());
          if (auto EC = Subsection.initialize(Reader))
            continue;
          Callback(Modi, Strings, Subsection);
        }
      });
}

Error DumpOutputStyle::dumpModules() {
  printHeader(P, "Modules");

  AutoIndent Indent(P);
  if (!File.hasPDBDbiStream()) {
    P.formatLine("DBI Stream not present");
    return Error::success();
  }

  ExitOnError Err("Unexpected error processing modules");

  auto &Stream = Err(File.getPDBDbiStream());

  const DbiModuleList &Modules = Stream.modules();
  uint32_t Count = Modules.getModuleCount();
  uint32_t Digits = NumDigits(Count);
  for (uint32_t I = 0; I < Count; ++I) {
    auto Modi = Modules.getModuleDescriptor(I);
    P.formatLine("Mod {0:4} | Name: `{1}`: ",
                 fmt_align(I, AlignStyle::Right, Digits), Modi.getModuleName());
    P.formatLine("           Obj: `{0}`: ", Modi.getObjFileName());
    P.formatLine("           debug stream: {0}, # files: {1}, has ec info: {2}",
                 Modi.getModuleStreamIndex(), Modi.getNumberOfFiles(),
                 Modi.hasECInfo());
    StringRef PdbFilePath =
        Err(Stream.getECName(Modi.getPdbFilePathNameIndex()));
    StringRef SrcFilePath =
        Err(Stream.getECName(Modi.getSourceFileNameIndex()));
    P.formatLine("           pdb file ni: {0} `{1}`, src file ni: {2} `{3}`",
                 Modi.getPdbFilePathNameIndex(), PdbFilePath,
                 Modi.getSourceFileNameIndex(), SrcFilePath);
  }
  return Error::success();
}

Error DumpOutputStyle::dumpModuleFiles() {
  printHeader(P, "Files");

  ExitOnError Err("Unexpected error processing modules");

  iterateModules(
      File, P, 11,
      [this, &Err](uint32_t Modi, StringsAndChecksumsPrinter &Strings) {
        auto &Stream = Err(File.getPDBDbiStream());

        const DbiModuleList &Modules = Stream.modules();
        for (const auto &F : Modules.source_files(Modi)) {
          Strings.formatFromFileName(P, F);
        }
      });
  return Error::success();
}

static void typesetLinesAndColumns(PDBFile &File, LinePrinter &P,
                                   uint32_t Start, const LineColumnEntry &E) {
  const uint32_t kMaxCharsPerLineNumber = 4; // 4 digit line number
  uint32_t MinColumnWidth = kMaxCharsPerLineNumber + 5;

  // Let's try to keep it under 100 characters
  constexpr uint32_t kMaxRowLength = 100;
  // At least 3 spaces between columns.
  uint32_t ColumnsPerRow = kMaxRowLength / (MinColumnWidth + 3);
  uint32_t ItemsLeft = E.LineNumbers.size();
  auto LineIter = E.LineNumbers.begin();
  while (ItemsLeft != 0) {
    uint32_t RowColumns = std::min(ItemsLeft, ColumnsPerRow);
    for (uint32_t I = 0; I < RowColumns; ++I) {
      LineInfo Line(LineIter->Flags);
      std::string LineStr;
      if (Line.isAlwaysStepInto())
        LineStr = "ASI";
      else if (Line.isNeverStepInto())
        LineStr = "NSI";
      else
        LineStr = utostr(Line.getStartLine());
      char Statement = Line.isStatement() ? ' ' : '!';
      P.format("{0} {1:X-} {2} ",
               fmt_align(LineStr, AlignStyle::Right, kMaxCharsPerLineNumber),
               fmt_align(Start + LineIter->Offset, AlignStyle::Right, 8, '0'),
               Statement);
      ++LineIter;
      --ItemsLeft;
    }
    P.NewLine();
  }
}

Error DumpOutputStyle::dumpLines() {
  printHeader(P, "Lines");

  uint32_t LastModi = UINT32_MAX;
  uint32_t LastNameIndex = UINT32_MAX;
  iterateModuleSubsections<DebugLinesSubsectionRef>(
      File, P, 4,
      [this, &LastModi, &LastNameIndex](uint32_t Modi,
                                        StringsAndChecksumsPrinter &Strings,
                                        DebugLinesSubsectionRef &Lines) {
        uint16_t Segment = Lines.header()->RelocSegment;
        uint32_t Begin = Lines.header()->RelocOffset;
        uint32_t End = Begin + Lines.header()->CodeSize;
        for (const auto &Block : Lines) {
          if (LastModi != Modi || LastNameIndex != Block.NameIndex) {
            LastModi = Modi;
            LastNameIndex = Block.NameIndex;
            Strings.formatFromChecksumsOffset(P, Block.NameIndex);
          }

          AutoIndent Indent(P, 2);
          P.formatLine("{0:X-4}:{1:X-8}-{2:X-8}, ", Segment, Begin, End);
          uint32_t Count = Block.LineNumbers.size();
          if (Lines.hasColumnInfo())
            P.format("line/column/addr entries = {0}", Count);
          else
            P.format("line/addr entries = {0}", Count);

          P.NewLine();
          typesetLinesAndColumns(File, P, Begin, Block);
        }
      });

  return Error::success();
}

Error DumpOutputStyle::dumpInlineeLines() {
  printHeader(P, "Inlinee Lines");

  iterateModuleSubsections<DebugInlineeLinesSubsectionRef>(
      File, P, 2,
      [this](uint32_t Modi, StringsAndChecksumsPrinter &Strings,
             DebugInlineeLinesSubsectionRef &Lines) {
        P.formatLine("{0,+8} | {1,+5} | {2}", "Inlinee", "Line", "Source File");
        for (const auto &Entry : Lines) {
          P.formatLine("{0,+8} | {1,+5} | ", Entry.Header->Inlinee,
                       fmtle(Entry.Header->SourceLineNum));
          Strings.formatFromChecksumsOffset(P, Entry.Header->FileID, true);
        }
        P.NewLine();
      });

  return Error::success();
}

Error DumpOutputStyle::dumpXmi() {
  printHeader(P, "Cross Module Imports");
  iterateModuleSubsections<DebugCrossModuleImportsSubsectionRef>(
      File, P, 2,
      [this](uint32_t Modi, StringsAndChecksumsPrinter &Strings,
             DebugCrossModuleImportsSubsectionRef &Imports) {
        P.formatLine("{0,=32} | {1}", "Imported Module", "Type IDs");

        for (const auto &Xmi : Imports) {
          auto ExpectedModule =
              Strings.getNameFromStringTable(Xmi.Header->ModuleNameOffset);
          StringRef Module;
          SmallString<32> ModuleStorage;
          if (!ExpectedModule) {
            Module = "(unknown module)";
            consumeError(ExpectedModule.takeError());
          } else
            Module = *ExpectedModule;
          if (Module.size() > 32) {
            ModuleStorage = "...";
            ModuleStorage += Module.take_back(32 - 3);
            Module = ModuleStorage;
          }
          std::vector<std::string> TIs;
          for (const auto I : Xmi.Imports)
            TIs.push_back(formatv("{0,+10:X+}", fmtle(I)));
          std::string Result =
              typesetItemList(TIs, P.getIndentLevel() + 35, 12, " ");
          P.formatLine("{0,+32} | {1}", Module, Result);
        }
      });

  return Error::success();
}

Error DumpOutputStyle::dumpXme() {
  printHeader(P, "Cross Module Exports");

  iterateModuleSubsections<DebugCrossModuleExportsSubsectionRef>(
      File, P, 2,
      [this](uint32_t Modi, StringsAndChecksumsPrinter &Strings,
             DebugCrossModuleExportsSubsectionRef &Exports) {
        P.formatLine("{0,-10} | {1}", "Local ID", "Global ID");
        for (const auto &Export : Exports) {
          P.formatLine("{0,+10:X+} | {1}", TypeIndex(Export.Local),
                       TypeIndex(Export.Global));
        }
      });

  return Error::success();
}

Error DumpOutputStyle::dumpStringTable() {
  printHeader(P, "String Table");

  AutoIndent Indent(P);
  auto IS = File.getStringTable();
  if (!IS) {
    P.formatLine("Not present in file");
    consumeError(IS.takeError());
    return Error::success();
  }

  if (IS->name_ids().empty()) {
    P.formatLine("Empty");
    return Error::success();
  }

  auto MaxID = std::max_element(IS->name_ids().begin(), IS->name_ids().end());
  uint32_t Digits = NumDigits(*MaxID);

  P.formatLine("{0} | {1}", fmt_align("ID", AlignStyle::Right, Digits),
               "String");

  std::vector<uint32_t> SortedIDs(IS->name_ids().begin(), IS->name_ids().end());
  std::sort(SortedIDs.begin(), SortedIDs.end());
  for (uint32_t I : SortedIDs) {
    auto ES = IS->getStringForID(I);
    llvm::SmallString<32> Str;
    if (!ES) {
      consumeError(ES.takeError());
      Str = "Error reading string";
    } else if (!ES->empty()) {
      Str.append("'");
      Str.append(*ES);
      Str.append("'");
    }

    if (!Str.empty())
      P.formatLine("{0} | {1}", fmt_align(I, AlignStyle::Right, Digits), Str);
  }
  return Error::success();
}

static void buildDepSet(LazyRandomTypeCollection &Types,
                        ArrayRef<TypeIndex> Indices,
                        std::map<TypeIndex, CVType> &DepSet) {
  SmallVector<TypeIndex, 4> DepList;
  for (const auto &I : Indices) {
    TypeIndex TI(I);
    if (DepSet.find(TI) != DepSet.end() || TI.isSimple() || TI.isNoneType())
      continue;

    CVType Type = Types.getType(TI);
    DepSet[TI] = Type;
    codeview::discoverTypeIndices(Type, DepList);
    buildDepSet(Types, DepList, DepSet);
  }
}

static void dumpFullTypeStream(LinePrinter &Printer,
                               LazyRandomTypeCollection &Types,
                               TpiStream &Stream, bool Bytes, bool Extras) {
  Printer.formatLine("Showing {0:N} records", Stream.getNumTypeRecords());
  uint32_t Width =
      NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());

  MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
                           Stream.getNumHashBuckets(), Stream.getHashValues());

  if (auto EC = codeview::visitTypeStream(Types, V)) {
    Printer.formatLine("An error occurred dumping type records: {0}",
                       toString(std::move(EC)));
  }
}

static void dumpPartialTypeStream(LinePrinter &Printer,
                                  LazyRandomTypeCollection &Types,
                                  TpiStream &Stream, ArrayRef<TypeIndex> TiList,
                                  bool Bytes, bool Extras, bool Deps) {
  uint32_t Width =
      NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());

  MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types,
                           Stream.getNumHashBuckets(), Stream.getHashValues());

  if (opts::dump::DumpTypeDependents) {
    // If we need to dump all dependents, then iterate each index and find
    // all dependents, adding them to a map ordered by TypeIndex.
    std::map<TypeIndex, CVType> DepSet;
    buildDepSet(Types, TiList, DepSet);

    Printer.formatLine(
        "Showing {0:N} records and their dependents ({1:N} records total)",
        TiList.size(), DepSet.size());

    for (auto &Dep : DepSet) {
      if (auto EC = codeview::visitTypeRecord(Dep.second, Dep.first, V))
        Printer.formatLine("An error occurred dumping type record {0}: {1}",
                           Dep.first, toString(std::move(EC)));
    }
  } else {
    Printer.formatLine("Showing {0:N} records.", TiList.size());

    for (const auto &I : TiList) {
      TypeIndex TI(I);
      CVType Type = Types.getType(TI);
      if (auto EC = codeview::visitTypeRecord(Type, TI, V))
        Printer.formatLine("An error occurred dumping type record {0}: {1}", TI,
                           toString(std::move(EC)));
    }
  }
}

Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
  assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);

  bool Present = false;
  bool DumpTypes = false;
  bool DumpBytes = false;
  bool DumpExtras = false;
  std::vector<uint32_t> Indices;
  if (StreamIdx == StreamTPI) {
    printHeader(P, "Types (TPI Stream)");
    Present = File.hasPDBTpiStream();
    DumpTypes = opts::dump::DumpTypes;
    DumpBytes = opts::dump::DumpTypeData;
    DumpExtras = opts::dump::DumpTypeExtras;
    Indices.assign(opts::dump::DumpTypeIndex.begin(),
                   opts::dump::DumpTypeIndex.end());
  } else if (StreamIdx == StreamIPI) {
    printHeader(P, "Types (IPI Stream)");
    Present = File.hasPDBIpiStream();
    DumpTypes = opts::dump::DumpIds;
    DumpBytes = opts::dump::DumpIdData;
    DumpExtras = opts::dump::DumpIdExtras;
    Indices.assign(opts::dump::DumpIdIndex.begin(),
                   opts::dump::DumpIdIndex.end());
  }

  AutoIndent Indent(P);
  if (!Present) {
    P.formatLine("Stream not present");
    return Error::success();
  }

  ExitOnError Err("Unexpected error processing types");

  auto &Stream = Err((StreamIdx == StreamTPI) ? File.getPDBTpiStream()
                                              : File.getPDBIpiStream());

  auto &Types = Err(initializeTypes(StreamIdx));

  if (DumpTypes || !Indices.empty()) {
    if (Indices.empty())
      dumpFullTypeStream(P, Types, Stream, DumpBytes, DumpExtras);
    else {
      std::vector<TypeIndex> TiList(Indices.begin(), Indices.end());
      dumpPartialTypeStream(P, Types, Stream, TiList, DumpBytes, DumpExtras,
                            opts::dump::DumpTypeDependents);
    }
  }

  if (DumpExtras) {
    P.NewLine();
    auto IndexOffsets = Stream.getTypeIndexOffsets();
    P.formatLine("Type Index Offsets:");
    for (const auto &IO : IndexOffsets) {
      AutoIndent Indent2(P);
      P.formatLine("TI: {0}, Offset: {1}", IO.Type, fmtle(IO.Offset));
    }

    P.NewLine();
    P.formatLine("Hash Adjusters:");
    auto &Adjusters = Stream.getHashAdjusters();
    auto &Strings = Err(File.getStringTable());
    for (const auto &A : Adjusters) {
      AutoIndent Indent2(P);
      auto ExpectedStr = Strings.getStringForID(A.first);
      TypeIndex TI(A.second);
      if (ExpectedStr)
        P.formatLine("`{0}` -> {1}", *ExpectedStr, TI);
      else {
        P.formatLine("unknown str id ({0}) -> {1}", A.first, TI);
        consumeError(ExpectedStr.takeError());
      }
    }
  }
  return Error::success();
}

Expected<codeview::LazyRandomTypeCollection &>
DumpOutputStyle::initializeTypes(uint32_t SN) {
  auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes;
  auto Tpi =
      (SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream();
  if (!Tpi)
    return Tpi.takeError();

  if (!TypeCollection) {
    auto &Types = Tpi->typeArray();
    uint32_t Count = Tpi->getNumTypeRecords();
    auto Offsets = Tpi->getTypeIndexOffsets();
    TypeCollection =
        llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
  }

  return *TypeCollection;
}

Error DumpOutputStyle::dumpModuleSyms() {
  printHeader(P, "Symbols");

  AutoIndent Indent(P);
  if (!File.hasPDBDbiStream()) {
    P.formatLine("DBI Stream not present");
    return Error::success();
  }

  ExitOnError Err("Unexpected error processing symbols");

  auto &Stream = Err(File.getPDBDbiStream());

  auto &Types = Err(initializeTypes(StreamTPI));

  const DbiModuleList &Modules = Stream.modules();
  uint32_t Count = Modules.getModuleCount();
  uint32_t Digits = NumDigits(Count);
  for (uint32_t I = 0; I < Count; ++I) {
    auto Modi = Modules.getModuleDescriptor(I);
    P.formatLine("Mod {0:4} | `{1}`: ", fmt_align(I, AlignStyle::Right, Digits),
                 Modi.getModuleName());
    uint16_t ModiStream = Modi.getModuleStreamIndex();
    if (ModiStream == kInvalidStreamIndex) {
      P.formatLine("           <symbols not present>");
      continue;
    }
    auto ModStreamData = MappedBlockStream::createIndexedStream(
        File.getMsfLayout(), File.getMsfBuffer(), ModiStream,
        File.getAllocator());

    ModuleDebugStreamRef ModS(Modi, std::move(ModStreamData));
    if (auto EC = ModS.reload()) {
      P.formatLine("Error loading module stream {0}.  {1}", I,
                   toString(std::move(EC)));
      continue;
    }

    SymbolVisitorCallbackPipeline Pipeline;
    SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
    MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Types);

    Pipeline.addCallbackToPipeline(Deserializer);
    Pipeline.addCallbackToPipeline(Dumper);
    CVSymbolVisitor Visitor(Pipeline);
    auto SS = ModS.getSymbolsSubstream();
    if (auto EC = Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset)) {
      P.formatLine("Error while processing symbol records.  {0}",
                   toString(std::move(EC)));
      continue;
    }
  }
  return Error::success();
}

Error DumpOutputStyle::dumpPublics() {
  printHeader(P, "Public Symbols");

  AutoIndent Indent(P);
  if (!File.hasPDBPublicsStream()) {
    P.formatLine("Publics stream not present");
    return Error::success();
  }

  ExitOnError Err("Error dumping publics stream");

  auto &Types = Err(initializeTypes(StreamTPI));
  auto &Publics = Err(File.getPDBPublicsStream());
  SymbolVisitorCallbackPipeline Pipeline;
  SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
  MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Types);

  Pipeline.addCallbackToPipeline(Deserializer);
  Pipeline.addCallbackToPipeline(Dumper);
  CVSymbolVisitor Visitor(Pipeline);

  auto ExpectedSymbols = Publics.getSymbolArray();
  if (!ExpectedSymbols) {
    P.formatLine("Could not read public symbol record stream");
    return Error::success();
  }

  if (auto EC = Visitor.visitSymbolStream(*ExpectedSymbols, 0))
    P.formatLine("Error while processing public symbol records.  {0}",
                 toString(std::move(EC)));

  return Error::success();
}

static std::string formatSectionCharacteristics(uint32_t IndentLevel,
                                                uint32_t C) {
  using SC = COFF::SectionCharacteristics;
  std::vector<std::string> Opts;
  if (C == COFF::SC_Invalid)
    return "invalid";
  if (C == 0)
    return "none";

  PUSH_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, "IMAGE_SCN_TYPE_NOLOAD");
  PUSH_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, "IMAGE_SCN_TYPE_NO_PAD");
  PUSH_FLAG(SC, IMAGE_SCN_CNT_CODE, C, "IMAGE_SCN_CNT_CODE");
  PUSH_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C,
            "IMAGE_SCN_CNT_INITIALIZED_DATA");
  PUSH_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C,
            "IMAGE_SCN_CNT_UNINITIALIZED_DATA");
  PUSH_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, "IMAGE_SCN_LNK_OTHER");
  PUSH_FLAG(SC, IMAGE_SCN_LNK_INFO, C, "IMAGE_SCN_LNK_INFO");
  PUSH_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, "IMAGE_SCN_LNK_REMOVE");
  PUSH_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, "IMAGE_SCN_LNK_COMDAT");
  PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, "IMAGE_SCN_MEM_PURGEABLE");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, "IMAGE_SCN_MEM_16BIT");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, "IMAGE_SCN_MEM_LOCKED");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, "IMAGE_SCN_MEM_PRELOAD");
  PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
  PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C,
                   "IMAGE_SCN_ALIGN_1BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C,
                   "IMAGE_SCN_ALIGN_2BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C,
                   "IMAGE_SCN_ALIGN_4BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C,
                   "IMAGE_SCN_ALIGN_8BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C,
                   "IMAGE_SCN_ALIGN_16BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C,
                   "IMAGE_SCN_ALIGN_32BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C,
                   "IMAGE_SCN_ALIGN_64BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C,
                   "IMAGE_SCN_ALIGN_128BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C,
                   "IMAGE_SCN_ALIGN_256BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C,
                   "IMAGE_SCN_ALIGN_512BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C,
                   "IMAGE_SCN_ALIGN_1024BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C,
                   "IMAGE_SCN_ALIGN_2048BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C,
                   "IMAGE_SCN_ALIGN_4096BYTES");
  PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C,
                   "IMAGE_SCN_ALIGN_8192BYTES");
  PUSH_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, "IMAGE_SCN_LNK_NRELOC_OVFL");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, "IMAGE_SCN_MEM_DISCARDABLE");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, "IMAGE_SCN_MEM_NOT_CACHED");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, "IMAGE_SCN_MEM_NOT_PAGED");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, "IMAGE_SCN_MEM_SHARED");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, "IMAGE_SCN_MEM_EXECUTE");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_READ, C, "IMAGE_SCN_MEM_READ");
  PUSH_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, "IMAGE_SCN_MEM_WRITE");
  return typesetItemList(Opts, IndentLevel, 3, " | ");
}

static std::string formatSegMapDescriptorFlag(uint32_t IndentLevel,
                                              OMFSegDescFlags Flags) {
  std::vector<std::string> Opts;
  if (Flags == OMFSegDescFlags::None)
    return "none";

  PUSH_FLAG(OMFSegDescFlags, Read, Flags, "read");
  PUSH_FLAG(OMFSegDescFlags, Write, Flags, "write");
  PUSH_FLAG(OMFSegDescFlags, Execute, Flags, "execute");
  PUSH_FLAG(OMFSegDescFlags, AddressIs32Bit, Flags, "32 bit addr");
  PUSH_FLAG(OMFSegDescFlags, IsSelector, Flags, "selector");
  PUSH_FLAG(OMFSegDescFlags, IsAbsoluteAddress, Flags, "absolute addr");
  PUSH_FLAG(OMFSegDescFlags, IsGroup, Flags, "group");
  return typesetItemList(Opts, IndentLevel, 4, " | ");
}

Error DumpOutputStyle::dumpSectionContribs() {
  printHeader(P, "Section Contributions");
  ExitOnError Err("Error dumping publics stream");

  AutoIndent Indent(P);
  if (!File.hasPDBDbiStream()) {
    P.formatLine(
        "Section contribs require a DBI Stream, which could not be loaded");
    return Error::success();
  }

  auto &Dbi = Err(File.getPDBDbiStream());

  class Visitor : public ISectionContribVisitor {
  public:
    Visitor(LinePrinter &P) : P(P) {}
    void visit(const SectionContrib &SC) override {
      P.formatLine(
          "SC  | mod = {2}, {0}, size = {1}, data crc = {3}, reloc crc = {4}",
          formatSegmentOffset(SC.ISect, SC.Off), fmtle(SC.Size), fmtle(SC.Imod),
          fmtle(SC.DataCrc), fmtle(SC.RelocCrc));
      P.formatLine("      {0}",
                   formatSectionCharacteristics(P.getIndentLevel() + 6,
                                                SC.Characteristics));
    }
    void visit(const SectionContrib2 &SC) override {
      P.formatLine("SC2 | mod = {2}, {0}, size = {1}, data crc = {3}, reloc "
                   "crc = {4}, coff section = {5}",
                   formatSegmentOffset(SC.Base.ISect, SC.Base.Off),
                   fmtle(SC.Base.Size), fmtle(SC.Base.Imod),
                   fmtle(SC.Base.DataCrc), fmtle(SC.Base.RelocCrc),
                   fmtle(SC.ISectCoff));
      P.formatLine("      {0}",
                   formatSectionCharacteristics(P.getIndentLevel() + 6,
                                                SC.Base.Characteristics));
    }

  private:
    LinePrinter &P;
  };

  Visitor V(P);
  Dbi.visitSectionContributions(V);
  return Error::success();
}

Error DumpOutputStyle::dumpSectionMap() {
  printHeader(P, "Section Map");
  ExitOnError Err("Error dumping section map");

  AutoIndent Indent(P);
  if (!File.hasPDBDbiStream()) {
    P.formatLine("Dumping the section map requires a DBI Stream, which could "
                 "not be loaded");
    return Error::success();
  }

  auto &Dbi = Err(File.getPDBDbiStream());

  uint32_t I = 0;
  for (auto &M : Dbi.getSectionMap()) {
    P.formatLine(
        "Section {0:4} | ovl = {0}, group = {1}, frame = {2}, name = {3}", I,
        fmtle(M.Ovl), fmtle(M.Group), fmtle(M.Frame), fmtle(M.SecName));
    P.formatLine("               class = {0}, offset = {1}, size = {2}",
                 fmtle(M.ClassName), fmtle(M.Offset), fmtle(M.SecByteLength));
    P.formatLine("               flags = {0}",
                 formatSegMapDescriptorFlag(
                     P.getIndentLevel() + 13,
                     static_cast<OMFSegDescFlags>(uint16_t(M.Flags))));
    ++I;
  }
  return Error::success();
}
