//===- DumpOutputStyle.cpp ------------------------------------ *- C++ --*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DumpOutputStyle.h"

#include "FormatUtil.h"
#include "InputFile.h"
#include "MinimalSymbolDumper.h"
#include "MinimalTypeDumper.h"
#include "StreamUtil.h"
#include "TypeReferenceTracker.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/DebugSymbolsSubsection.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/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.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/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/SymbolStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"

#include <cctype>

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

DumpOutputStyle::DumpOutputStyle(InputFile &File)
    : File(File), P(2, false, outs()) {
  if (opts::dump::DumpTypeRefStats)
    RefTracker.reset(new TypeReferenceTracker(File));
}

DumpOutputStyle::~DumpOutputStyle() {}

PDBFile &DumpOutputStyle::getPdb() { return File.pdb(); }
object::COFFObjectFile &DumpOutputStyle::getObj() { return File.obj(); }

void DumpOutputStyle::printStreamNotValidForObj() {
  AutoIndent Indent(P, 4);
  P.formatLine("Dumping this stream is not valid for object files");
}

void DumpOutputStyle::printStreamNotPresent(StringRef StreamName) {
  AutoIndent Indent(P, 4);
  P.formatLine("{0} stream not present", StreamName);
}

Error DumpOutputStyle::dump() {
  // Walk symbols & globals if we are supposed to mark types referenced.
  if (opts::dump::DumpTypeRefStats)
    RefTracker->mark();

  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::DumpSymbolStats) {
    if (auto EC = dumpSymbolStats())
      return EC;
    P.NewLine();
  }

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

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

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

  if (opts::dump::DumpStringTable || opts::dump::DumpStringTableDetails) {
    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::DumpFpo) {
    if (auto EC = dumpFpo())
      return EC;
  }

  if (File.isObj()) {
    if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() ||
        opts::dump::DumpTypeExtras)
      if (auto EC = dumpTypesFromObjectFile())
        return EC;
  } else {
    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::DumpGSIRecords) {
    if (auto EC = dumpGSIRecords())
      return EC;
  }

  if (opts::dump::DumpGlobals) {
    if (auto EC = dumpGlobals())
      return EC;
  }

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

  if (opts::dump::DumpSymbols) {
    auto EC = File.isPdb() ? dumpModuleSymsForPdb() : dumpModuleSymsForObj();
    if (EC)
      return EC;
  }

  if (opts::dump::DumpTypeRefStats) {
    if (auto EC = dumpTypeRefStats())
      return EC;
  }

  if (opts::dump::DumpSectionHeaders) {
    if (auto EC = dumpSectionHeaders())
      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");

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Invalid PDB Format: ");

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

  auto &PS = Err(getPdb().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}", getPdb().hasPDBDbiStream());
  P.formatLine("Has Types: {0}", getPdb().hasPDBTpiStream());
  P.formatLine("Has IDs: {0}", getPdb().hasPDBIpiStream());
  P.formatLine("Has Globals: {0}", getPdb().hasPDBGlobalsStream());
  P.formatLine("Has Publics: {0}", getPdb().hasPDBPublicsStream());
  if (getPdb().hasPDBDbiStream()) {
    auto &DBI = Err(getPdb().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();
}

static StatCollection getSymbolStats(const SymbolGroup &SG,
                                     StatCollection &CumulativeStats) {
  StatCollection Stats;
  if (SG.getFile().isPdb() && SG.hasDebugStream()) {
    // For PDB files, all symbols are packed into one stream.
    for (const auto &S : SG.getPdbModuleStream().symbols(nullptr)) {
      Stats.update(S.kind(), S.length());
      CumulativeStats.update(S.kind(), S.length());
    }
    return Stats;
  }

  for (const auto &SS : SG.getDebugSubsections()) {
    // For object files, all symbols are spread across multiple Symbol
    // subsections of a given .debug$S section.
    if (SS.kind() != DebugSubsectionKind::Symbols)
      continue;
    DebugSymbolsSubsectionRef Symbols;
    BinaryStreamReader Reader(SS.getRecordData());
    cantFail(Symbols.initialize(Reader));
    for (const auto &S : Symbols) {
      Stats.update(S.kind(), S.length());
      CumulativeStats.update(S.kind(), S.length());
    }
  }
  return Stats;
}

static StatCollection getChunkStats(const SymbolGroup &SG,
                                    StatCollection &CumulativeStats) {
  StatCollection Stats;
  for (const auto &Chunk : SG.getDebugSubsections()) {
    Stats.update(uint32_t(Chunk.kind()), Chunk.getRecordLength());
    CumulativeStats.update(uint32_t(Chunk.kind()), Chunk.getRecordLength());
  }
  return Stats;
}

static inline std::string formatModuleDetailKind(DebugSubsectionKind K) {
  return formatChunkKind(K, false);
}

static inline std::string formatModuleDetailKind(SymbolKind K) {
  return formatSymbolKind(K);
}

// Get the stats sorted by size, descending.
std::vector<StatCollection::KindAndStat>
StatCollection::getStatsSortedBySize() const {
  std::vector<KindAndStat> SortedStats(Individual.begin(), Individual.end());
  std::stable_sort(SortedStats.begin(), SortedStats.end(),
                   [](const KindAndStat &LHS, const KindAndStat &RHS) {
                     return LHS.second.Size > RHS.second.Size;
                   });
  return SortedStats;
}

template <typename Kind>
static void printModuleDetailStats(LinePrinter &P, StringRef Label,
                                   const StatCollection &Stats) {
  P.NewLine();
  P.formatLine("  {0}", Label);
  AutoIndent Indent(P);
  P.formatLine("{0,40}: {1,7} entries ({2,12:N} bytes)", "Total",
               Stats.Totals.Count, Stats.Totals.Size);
  P.formatLine("{0}", fmt_repeat('-', 74));

  for (const auto &K : Stats.getStatsSortedBySize()) {
    std::string KindName = formatModuleDetailKind(Kind(K.first));
    P.formatLine("{0,40}: {1,7} entries ({2,12:N} bytes)", KindName,
                 K.second.Count, K.second.Size);
  }
}

static bool isMyCode(const SymbolGroup &Group) {
  if (Group.getFile().isObj())
    return true;

  StringRef Name = Group.name();
  if (Name.startswith("Import:"))
    return false;
  if (Name.endswith_lower(".dll"))
    return false;
  if (Name.equals_lower("* linker *"))
    return false;
  if (Name.startswith_lower("f:\\binaries\\Intermediate\\vctools"))
    return false;
  if (Name.startswith_lower("f:\\dd\\vctools\\crt"))
    return false;
  return true;
}

static bool shouldDumpSymbolGroup(uint32_t Idx, const SymbolGroup &Group) {
  if (opts::dump::JustMyCode && !isMyCode(Group))
    return false;

  // If the arg was not specified on the command line, always dump all modules.
  if (opts::dump::DumpModi.getNumOccurrences() == 0)
    return true;

  // Otherwise, only dump if this is the same module specified.
  return (opts::dump::DumpModi == Idx);
}

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

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  AutoIndent Indent(P);

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

  uint32_t StreamCount = getPdb().getNumStreams();
  uint32_t MaxStreamSize = getPdb().getMaxStreamSize();

  for (uint16_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
    P.formatLine(
        "Stream {0} ({1} bytes): [{2}]",
        fmt_align(StreamIdx, AlignStyle::Right, NumDigits(StreamCount)),
        fmt_align(getPdb().getStreamByteSize(StreamIdx), AlignStyle::Right,
                  NumDigits(MaxStreamSize)),
        StreamPurposes[StreamIdx].getLongName());

    if (opts::dump::DumpStreamBlocks) {
      auto Blocks = getPdb().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 = File.createIndexedStream(ModiStream);

  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);
}

template <typename CallbackT>
static void
iterateOneModule(InputFile &File, const Optional<PrintScope> &HeaderScope,
                 const SymbolGroup &SG, uint32_t Modi, CallbackT Callback) {
  if (HeaderScope) {
    HeaderScope->P.formatLine(
        "Mod {0:4} | `{1}`: ",
        fmt_align(Modi, AlignStyle::Right, HeaderScope->LabelWidth), SG.name());
  }

  AutoIndent Indent(HeaderScope);
  Callback(Modi, SG);
}

template <typename CallbackT>
static void iterateSymbolGroups(InputFile &Input,
                                const Optional<PrintScope> &HeaderScope,
                                CallbackT Callback) {
  AutoIndent Indent(HeaderScope);

  ExitOnError Err("Unexpected error processing modules: ");

  if (opts::dump::DumpModi.getNumOccurrences() > 0) {
    assert(opts::dump::DumpModi.getNumOccurrences() == 1);
    uint32_t Modi = opts::dump::DumpModi;
    SymbolGroup SG(&Input, Modi);
    iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)), SG,
                     Modi, Callback);
    return;
  }

  uint32_t I = 0;

  for (const auto &SG : Input.symbol_groups()) {
    if (shouldDumpSymbolGroup(I, SG))
      iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)), SG, I,
                       Callback);

    ++I;
  }
}

template <typename SubsectionT>
static void iterateModuleSubsections(
    InputFile &File, const Optional<PrintScope> &HeaderScope,
    llvm::function_ref<void(uint32_t, const SymbolGroup &, SubsectionT &)>
        Callback) {

  iterateSymbolGroups(File, HeaderScope,
                      [&](uint32_t Modi, const SymbolGroup &SG) {
                        for (const auto &SS : SG.getDebugSubsections()) {
                          SubsectionT Subsection;

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

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

static Expected<std::pair<std::unique_ptr<MappedBlockStream>,
                          ArrayRef<llvm::object::coff_section>>>
loadSectionHeaders(PDBFile &File, DbgHeaderType Type) {
  if (!File.hasPDBDbiStream())
    return make_error<StringError>(
        "Section headers require a DBI Stream, which could not be loaded",
        inconvertibleErrorCode());

  auto &Dbi = cantFail(File.getPDBDbiStream());
  uint32_t SI = Dbi.getDebugStreamIndex(Type);

  if (SI == kInvalidStreamIndex)
    return make_error<StringError>(
        "PDB does not contain the requested image section header type",
        inconvertibleErrorCode());

  auto Stream = File.createIndexedStream(SI);
  if (!Stream)
    return make_error<StringError>("Could not load the required stream data",
                                   inconvertibleErrorCode());

  ArrayRef<object::coff_section> Headers;
  if (Stream->getLength() % sizeof(object::coff_section) != 0)
    return make_error<StringError>(
        "Section header array size is not a multiple of section header size",
        inconvertibleErrorCode());

  uint32_t NumHeaders = Stream->getLength() / sizeof(object::coff_section);
  BinaryStreamReader Reader(*Stream);
  cantFail(Reader.readArray(Headers, NumHeaders));
  return std::make_pair(std::move(Stream), Headers);
}

static std::vector<std::string> getSectionNames(PDBFile &File) {
  auto ExpectedHeaders = loadSectionHeaders(File, DbgHeaderType::SectionHdr);
  if (!ExpectedHeaders)
    return {};

  std::unique_ptr<MappedBlockStream> Stream;
  ArrayRef<object::coff_section> Headers;
  std::tie(Stream, Headers) = std::move(*ExpectedHeaders);
  std::vector<std::string> Names;
  for (const auto &H : Headers)
    Names.push_back(H.Name);
  return Names;
}

static void dumpSectionContrib(LinePrinter &P, const SectionContrib &SC,
                               ArrayRef<std::string> SectionNames,
                               uint32_t FieldWidth) {
  std::string NameInsert;
  if (SC.ISect > 0 && SC.ISect <= SectionNames.size()) {
    StringRef SectionName = SectionNames[SC.ISect - 1];
    NameInsert = formatv("[{0}]", SectionName).str();
  } else
    NameInsert = "[???]";
  P.formatLine("SC{5}  | 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),
               fmt_align(NameInsert, AlignStyle::Left, FieldWidth + 2));
  AutoIndent Indent(P, FieldWidth + 2);
  P.formatLine("      {0}",
               formatSectionCharacteristics(P.getIndentLevel() + 6,
                                            SC.Characteristics, 3, " | "));
}

static void dumpSectionContrib(LinePrinter &P, const SectionContrib2 &SC,
                               ArrayRef<std::string> SectionNames,
                               uint32_t FieldWidth) {
  P.formatLine("SC2[{6}] | 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, 3, " | "));
}

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

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Unexpected error processing modules: ");

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

  const DbiModuleList &Modules = Stream.modules();
  iterateSymbolGroups(
      File, PrintScope{P, 11}, [&](uint32_t Modi, const SymbolGroup &Strings) {
        auto Desc = Modules.getModuleDescriptor(Modi);
        if (opts::dump::DumpSectionContribs) {
          std::vector<std::string> Sections = getSectionNames(getPdb());
          dumpSectionContrib(P, Desc.getSectionContrib(), Sections, 0);
        }
        P.formatLine("Obj: `{0}`: ", Desc.getObjFileName());
        P.formatLine("debug stream: {0}, # files: {1}, has ec info: {2}",
                     Desc.getModuleStreamIndex(), Desc.getNumberOfFiles(),
                     Desc.hasECInfo());
        StringRef PdbFilePath =
            Err(Stream.getECName(Desc.getPdbFilePathNameIndex()));
        StringRef SrcFilePath =
            Err(Stream.getECName(Desc.getSourceFileNameIndex()));
        P.formatLine("pdb file ni: {0} `{1}`, src file ni: {2} `{3}`",
                     Desc.getPdbFilePathNameIndex(), PdbFilePath,
                     Desc.getSourceFileNameIndex(), SrcFilePath);
      });
  return Error::success();
}

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

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  ExitOnError Err("Unexpected error processing modules: ");

  iterateSymbolGroups(File, PrintScope{P, 11},
                      [this, &Err](uint32_t Modi, const SymbolGroup &Strings) {
                        auto &Stream = Err(getPdb().getPDBDbiStream());

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

Error DumpOutputStyle::dumpSymbolStats() {
  printHeader(P, "Module Stats");

  if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  ExitOnError Err("Unexpected error processing modules: ");

  StatCollection SymStats;
  StatCollection ChunkStats;

  Optional<PrintScope> Scope;
  if (File.isPdb())
    Scope.emplace(P, 2);

  iterateSymbolGroups(File, Scope, [&](uint32_t Modi, const SymbolGroup &SG) {
    StatCollection SS = getSymbolStats(SG, SymStats);
    StatCollection CS = getChunkStats(SG, ChunkStats);

    if (SG.getFile().isPdb()) {
      AutoIndent Indent(P);
      auto Modules = cantFail(File.pdb().getPDBDbiStream()).modules();
      uint32_t ModCount = Modules.getModuleCount();
      DbiModuleDescriptor Desc = Modules.getModuleDescriptor(Modi);
      uint32_t StreamIdx = Desc.getModuleStreamIndex();

      if (StreamIdx == kInvalidStreamIndex) {
        P.formatLine("Mod {0} (debug info not present): [{1}]",
                     fmt_align(Modi, AlignStyle::Right, NumDigits(ModCount)),
                     Desc.getModuleName());
        return;
      }
      P.formatLine("Stream {0}, {1} bytes", StreamIdx,
                   getPdb().getStreamByteSize(StreamIdx));

      printModuleDetailStats<SymbolKind>(P, "Symbols", SS);
      printModuleDetailStats<DebugSubsectionKind>(P, "Chunks", CS);
    }
  });

  if (SymStats.Totals.Count > 0) {
    P.printLine("  Summary |");
    AutoIndent Indent(P, 4);
    printModuleDetailStats<SymbolKind>(P, "Symbols", SymStats);
    printModuleDetailStats<DebugSubsectionKind>(P, "Chunks", ChunkStats);
  }

  return Error::success();
}

Error DumpOutputStyle::dumpTypeStats() {
  printHeader(P, "Type Record Stats");

  // Iterate the types, categorize by kind, accumulate size stats.
  StatCollection TypeStats;
  LazyRandomTypeCollection &Types = File.types();
  for (Optional<TypeIndex> TI = Types.getFirst(); TI; TI = Types.getNext(*TI)) {
    CVType Type = Types.getType(*TI);
    TypeStats.update(uint32_t(Type.kind()), Type.length());
  }

  P.NewLine();
  P.formatLine("  Types");
  AutoIndent Indent(P);
  P.formatLine("{0,14}: {1,7} entries ({2,12:N} bytes, {3,7} avg)", "Total",
               TypeStats.Totals.Count, TypeStats.Totals.Size,
               (double)TypeStats.Totals.Size / TypeStats.Totals.Count);
  P.formatLine("{0}", fmt_repeat('-', 74));

  for (const auto &K : TypeStats.getStatsSortedBySize()) {
    P.formatLine("{0,14}: {1,7} entries ({2,12:N} bytes, {3,7} avg)",
                 formatTypeLeafKind(TypeLeafKind(K.first)), K.second.Count,
                 K.second.Size, (double)K.second.Size / K.second.Count);
  }


  return Error::success();
}

static bool isValidNamespaceIdentifier(StringRef S) {
  if (S.empty())
    return false;

  if (std::isdigit(S[0]))
    return false;

  return llvm::all_of(S, [](char C) { return std::isalnum(C); });
}

namespace {
constexpr uint32_t kNoneUdtKind = 0;
constexpr uint32_t kSimpleUdtKind = 1;
constexpr uint32_t kUnknownUdtKind = 2;
const StringRef NoneLabel("<none type>");
const StringRef SimpleLabel("<simple type>");
const StringRef UnknownLabel("<unknown type>");

} // namespace

static StringRef getUdtStatLabel(uint32_t Kind) {
  if (Kind == kNoneUdtKind)
    return NoneLabel;

  if (Kind == kSimpleUdtKind)
    return SimpleLabel;

  if (Kind == kUnknownUdtKind)
    return UnknownLabel;

  return formatTypeLeafKind(static_cast<TypeLeafKind>(Kind));
}

static uint32_t getLongestTypeLeafName(const StatCollection &Stats) {
  size_t L = 0;
  for (const auto &Stat : Stats.Individual) {
    StringRef Label = getUdtStatLabel(Stat.first);
    L = std::max(L, Label.size());
  }
  return static_cast<uint32_t>(L);
}

Error DumpOutputStyle::dumpUdtStats() {
  printHeader(P, "S_UDT Record Stats");

  if (File.isPdb() && !getPdb().hasPDBGlobalsStream()) {
    printStreamNotPresent("Globals");
    return Error::success();
  }

  StatCollection UdtStats;
  StatCollection UdtTargetStats;
  AutoIndent Indent(P, 4);

  auto &TpiTypes = File.types();

  StringMap<StatCollection::Stat> NamespacedStats;

  size_t LongestNamespace = 0;
  auto HandleOneSymbol = [&](const CVSymbol &Sym) {
    if (Sym.kind() != SymbolKind::S_UDT)
      return;
    UdtStats.update(SymbolKind::S_UDT, Sym.length());

    UDTSym UDT = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(Sym));

    uint32_t Kind = 0;
    uint32_t RecordSize = 0;

    if (UDT.Type.isNoneType())
      Kind = kNoneUdtKind;
    else if (UDT.Type.isSimple())
      Kind = kSimpleUdtKind;
    else if (Optional<CVType> T = TpiTypes.tryGetType(UDT.Type)) {
      Kind = T->kind();
      RecordSize = T->length();
    } else
      Kind = kUnknownUdtKind;

    UdtTargetStats.update(Kind, RecordSize);

    size_t Pos = UDT.Name.find("::");
    if (Pos == StringRef::npos)
      return;

    StringRef Scope = UDT.Name.take_front(Pos);
    if (Scope.empty() || !isValidNamespaceIdentifier(Scope))
      return;

    LongestNamespace = std::max(LongestNamespace, Scope.size());
    NamespacedStats[Scope].update(RecordSize);
  };

  P.NewLine();

  if (File.isPdb()) {
    auto &SymbolRecords = cantFail(getPdb().getPDBSymbolStream());
    auto ExpGlobals = getPdb().getPDBGlobalsStream();
    if (!ExpGlobals)
      return ExpGlobals.takeError();

    for (uint32_t PubSymOff : ExpGlobals->getGlobalsTable()) {
      CVSymbol Sym = SymbolRecords.readRecord(PubSymOff);
      HandleOneSymbol(Sym);
    }
  } else {
    for (const auto &Sec : File.symbol_groups()) {
      for (const auto &SS : Sec.getDebugSubsections()) {
        if (SS.kind() != DebugSubsectionKind::Symbols)
          continue;

        DebugSymbolsSubsectionRef Symbols;
        BinaryStreamReader Reader(SS.getRecordData());
        cantFail(Symbols.initialize(Reader));
        for (const auto &S : Symbols)
          HandleOneSymbol(S);
      }
    }
  }

  LongestNamespace += StringRef(" namespace ''").size();
  size_t LongestTypeLeafKind = getLongestTypeLeafName(UdtTargetStats);
  size_t FieldWidth = std::max(LongestNamespace, LongestTypeLeafKind);

  // Compute the max number of digits for count and size fields, including comma
  // separators.
  StringRef CountHeader("Count");
  StringRef SizeHeader("Size");
  size_t CD = NumDigits(UdtStats.Totals.Count);
  CD += (CD - 1) / 3;
  CD = std::max(CD, CountHeader.size());

  size_t SD = NumDigits(UdtStats.Totals.Size);
  SD += (SD - 1) / 3;
  SD = std::max(SD, SizeHeader.size());

  uint32_t TableWidth = FieldWidth + 3 + CD + 2 + SD + 1;

  P.formatLine("{0} | {1}  {2}",
               fmt_align("Record Kind", AlignStyle::Right, FieldWidth),
               fmt_align(CountHeader, AlignStyle::Right, CD),
               fmt_align(SizeHeader, AlignStyle::Right, SD));

  P.formatLine("{0}", fmt_repeat('-', TableWidth));
  for (const auto &Stat : UdtTargetStats.getStatsSortedBySize()) {
    StringRef Label = getUdtStatLabel(Stat.first);
    P.formatLine("{0} | {1:N}  {2:N}",
                 fmt_align(Label, AlignStyle::Right, FieldWidth),
                 fmt_align(Stat.second.Count, AlignStyle::Right, CD),
                 fmt_align(Stat.second.Size, AlignStyle::Right, SD));
  }
  P.formatLine("{0}", fmt_repeat('-', TableWidth));
  P.formatLine("{0} | {1:N}  {2:N}",
               fmt_align("Total (S_UDT)", AlignStyle::Right, FieldWidth),
               fmt_align(UdtStats.Totals.Count, AlignStyle::Right, CD),
               fmt_align(UdtStats.Totals.Size, AlignStyle::Right, SD));
  P.formatLine("{0}", fmt_repeat('-', TableWidth));
  struct StrAndStat {
    StringRef Key;
    StatCollection::Stat Stat;
  };

  // Print namespace stats in descending order of size.
  std::vector<StrAndStat> NamespacedStatsSorted;
  for (const auto &Stat : NamespacedStats)
    NamespacedStatsSorted.push_back({Stat.getKey(), Stat.second});
  std::stable_sort(NamespacedStatsSorted.begin(), NamespacedStatsSorted.end(),
                   [](const StrAndStat &L, const StrAndStat &R) {
                     return L.Stat.Size > R.Stat.Size;
                   });
  for (const auto &Stat : NamespacedStatsSorted) {
    std::string Label = formatv("namespace '{0}'", Stat.Key);
    P.formatLine("{0} | {1:N}  {2:N}",
                 fmt_align(Label, AlignStyle::Right, FieldWidth),
                 fmt_align(Stat.Stat.Count, AlignStyle::Right, CD),
                 fmt_align(Stat.Stat.Size, AlignStyle::Right, SD));
  }
  return Error::success();
}

static void typesetLinesAndColumns(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");

  if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  uint32_t LastModi = UINT32_MAX;
  uint32_t LastNameIndex = UINT32_MAX;
  iterateModuleSubsections<DebugLinesSubsectionRef>(
      File, PrintScope{P, 4},
      [this, &LastModi, &LastNameIndex](uint32_t Modi,
                                        const SymbolGroup &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(P, Begin, Block);
        }
      });

  return Error::success();
}

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

  if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  iterateModuleSubsections<DebugInlineeLinesSubsectionRef>(
      File, PrintScope{P, 2},
      [this](uint32_t Modi, const SymbolGroup &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");

  if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  iterateModuleSubsections<DebugCrossModuleImportsSubsectionRef>(
      File, PrintScope{P, 2},
      [this](uint32_t Modi, const SymbolGroup &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");

  if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  iterateModuleSubsections<DebugCrossModuleExportsSubsectionRef>(
      File, PrintScope{P, 2},
      [this](uint32_t Modi, const SymbolGroup &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();
}

std::string formatFrameType(object::frame_type FT) {
  switch (FT) {
  case object::frame_type::Fpo:
    return "FPO";
  case object::frame_type::NonFpo:
    return "Non-FPO";
  case object::frame_type::Trap:
    return "Trap";
  case object::frame_type::Tss:
    return "TSS";
  }
  return "<unknown>";
}

Error DumpOutputStyle::dumpOldFpo(PDBFile &File) {
  printHeader(P, "Old FPO Data");

  ExitOnError Err("Error dumping old fpo data:");
  auto &Dbi = Err(File.getPDBDbiStream());

  if (!Dbi.hasOldFpoRecords()) {
    printStreamNotPresent("FPO");
    return Error::success();
  }

  const FixedStreamArray<object::FpoData>& Records = Dbi.getOldFpoRecords();

  P.printLine("  RVA    | Code | Locals | Params | Prolog | Saved Regs | Use "
              "BP | Has SEH | Frame Type");

  for (const object::FpoData &FD : Records) {
    P.formatLine("{0:X-8} | {1,4} | {2,6} | {3,6} | {4,6} | {5,10} | {6,6} | "
                 "{7,7} | {8,9}",
                 uint32_t(FD.Offset), uint32_t(FD.Size), uint32_t(FD.NumLocals),
                 uint32_t(FD.NumParams), FD.getPrologSize(),
                 FD.getNumSavedRegs(), FD.useBP(), FD.hasSEH(),
                 formatFrameType(FD.getFP()));
  }
  return Error::success();
}

Error DumpOutputStyle::dumpNewFpo(PDBFile &File) {
  printHeader(P, "New FPO Data");

  ExitOnError Err("Error dumping new fpo data:");
  auto &Dbi = Err(File.getPDBDbiStream());

  if (!Dbi.hasNewFpoRecords()) {
    printStreamNotPresent("New FPO");
    return Error::success();
  }

  const DebugFrameDataSubsectionRef& FDS = Dbi.getNewFpoRecords();

  P.printLine("  RVA    | Code | Locals | Params | Stack | Prolog | Saved Regs "
              "| Has SEH | Has C++EH | Start | Program");
  for (const FrameData &FD : FDS) {
    bool IsFuncStart = FD.Flags & FrameData::IsFunctionStart;
    bool HasEH = FD.Flags & FrameData::HasEH;
    bool HasSEH = FD.Flags & FrameData::HasSEH;

    auto &StringTable = Err(File.getStringTable());

    auto Program = Err(StringTable.getStringForID(FD.FrameFunc));
    P.formatLine("{0:X-8} | {1,4} | {2,6} | {3,6} | {4,5} | {5,6} | {6,10} | "
                 "{7,7} | {8,9} | {9,5} | {10}",
                 uint32_t(FD.RvaStart), uint32_t(FD.CodeSize),
                 uint32_t(FD.LocalSize), uint32_t(FD.ParamsSize),
                 uint32_t(FD.MaxStackSize), uint16_t(FD.PrologSize),
                 uint16_t(FD.SavedRegsSize), HasSEH, HasEH, IsFuncStart,
                 Program);
  }
  return Error::success();
}

Error DumpOutputStyle::dumpFpo() {
  if (!File.isPdb()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  PDBFile &File = getPdb();
  if (!File.hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  if (auto EC = dumpOldFpo(File))
    return EC;
  if (auto EC = dumpNewFpo(File))
    return EC;
  return Error::success();
}

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

  if (opts::dump::DumpStringTable) {
    if (IS->name_ids().empty())
      P.formatLine("Empty");
    else {
      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());
      llvm::sort(SortedIDs);
      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);
      }
    }
  }

  if (opts::dump::DumpStringTableDetails) {
    P.NewLine();
    {
      P.printLine("String Table Header:");
      AutoIndent Indent(P);
      P.formatLine("Signature: {0}", IS->getSignature());
      P.formatLine("Hash Version: {0}", IS->getHashVersion());
      P.formatLine("Name Buffer Size: {0}", IS->getByteSize());
      P.NewLine();
    }

    BinaryStreamRef NameBuffer = IS->getStringTable().getBuffer();
    ArrayRef<uint8_t> Contents;
    cantFail(NameBuffer.readBytes(0, NameBuffer.getLength(), Contents));
    P.formatBinary("Name Buffer", Contents, 0);
    P.NewLine();
    {
      P.printLine("Hash Table:");
      AutoIndent Indent(P);
      P.formatLine("Bucket Count: {0}", IS->name_ids().size());
      for (const auto &Entry : enumerate(IS->name_ids()))
        P.formatLine("Bucket[{0}] : {1}", Entry.index(),
                     uint32_t(Entry.value()));
      P.formatLine("Name Count: {0}", IS->getNameCount());
    }
  }
  return Error::success();
}

Error DumpOutputStyle::dumpStringTableFromObj() {
  iterateModuleSubsections<DebugStringTableSubsectionRef>(
      File, PrintScope{P, 4},
      [&](uint32_t Modi, const SymbolGroup &Strings,
          DebugStringTableSubsectionRef &Strings2) {
        BinaryStreamRef StringTableBuffer = Strings2.getBuffer();
        BinaryStreamReader Reader(StringTableBuffer);
        while (Reader.bytesRemaining() > 0) {
          StringRef Str;
          uint32_t Offset = Reader.getOffset();
          cantFail(Reader.readCString(Str));
          if (Str.empty())
            continue;

          P.formatLine("{0} | {1}", fmt_align(Offset, AlignStyle::Right, 4),
                       Str);
        }
      });
  return Error::success();
}

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

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Invalid PDB File: ");

  auto &IS = Err(File.pdb().getPDBInfoStream());
  const NamedStreamMap &NS = IS.getNamedStreams();
  for (const auto &Entry : NS.entries()) {
    P.printLine(Entry.getKey());
    AutoIndent Indent2(P, 2);
    P.formatLine("Index: {0}", Entry.getValue());
    P.formatLine("Size in bytes: {0}",
                 File.pdb().getStreamByteSize(Entry.getValue()));
  }

  return Error::success();
}

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

  if (File.isPdb())
    return dumpStringTableFromPdb();

  return dumpStringTableFromObj();
}

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,
                   TypeReferenceTracker *RefTracker, uint32_t NumTypeRecords,
                   uint32_t NumHashBuckets,
                   FixedStreamArray<support::ulittle32_t> HashValues,
                   TpiStream *Stream, bool Bytes, bool Extras) {

  Printer.formatLine("Showing {0:N} records", NumTypeRecords);
  uint32_t Width = NumDigits(TypeIndex::FirstNonSimpleIndex + NumTypeRecords);

  MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, RefTracker,
                           NumHashBuckets, HashValues, Stream);

  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,
                                  TypeReferenceTracker *RefTracker,
                                  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, RefTracker,
                           Stream.getNumHashBuckets(), Stream.getHashValues(),
                           &Stream);

  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::dumpTypesFromObjectFile() {
  LazyRandomTypeCollection Types(100);

  for (const auto &S : getObj().sections()) {
    StringRef SectionName;
    if (auto EC = S.getName(SectionName))
      return errorCodeToError(EC);

    // .debug$T is a standard CodeView type section, while .debug$P is the same
    // format but used for MSVC precompiled header object files.
    if (SectionName == ".debug$T")
      printHeader(P, "Types (.debug$T)");
    else if (SectionName == ".debug$P")
      printHeader(P, "Precompiled Types (.debug$P)");
    else
      continue;

    StringRef Contents;
    if (auto EC = S.getContents(Contents))
      return errorCodeToError(EC);

    uint32_t Magic;
    BinaryStreamReader Reader(Contents, llvm::support::little);
    if (auto EC = Reader.readInteger(Magic))
      return EC;
    if (Magic != COFF::DEBUG_SECTION_MAGIC)
      return make_error<StringError>("Invalid CodeView debug section.",
                                     inconvertibleErrorCode());

    Types.reset(Reader, 100);

    if (opts::dump::DumpTypes) {
      dumpFullTypeStream(P, Types, RefTracker.get(), 0, 0, {}, nullptr,
                         opts::dump::DumpTypeData, false);
    } else if (opts::dump::DumpTypeExtras) {
      auto LocalHashes = LocallyHashedType::hashTypeCollection(Types);
      auto GlobalHashes = GloballyHashedType::hashTypeCollection(Types);
      assert(LocalHashes.size() == GlobalHashes.size());

      P.formatLine("Local / Global hashes:");
      TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
      for (const auto &H : zip(LocalHashes, GlobalHashes)) {
        AutoIndent Indent2(P);
        LocallyHashedType &L = std::get<0>(H);
        GloballyHashedType &G = std::get<1>(H);

        P.formatLine("TI: {0}, LocalHash: {1:X}, GlobalHash: {2}", TI, L, G);

        ++TI;
      }
      P.NewLine();
    }
  }

  return Error::success();
}

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

  if (StreamIdx == StreamTPI) {
    printHeader(P, "Types (TPI Stream)");
  } else if (StreamIdx == StreamIPI) {
    printHeader(P, "Types (IPI Stream)");
  }

  assert(!File.isObj());

  bool Present = false;
  bool DumpTypes = false;
  bool DumpBytes = false;
  bool DumpExtras = false;
  std::vector<uint32_t> Indices;
  if (StreamIdx == StreamTPI) {
    Present = getPdb().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) {
    Present = getPdb().hasPDBIpiStream();
    DumpTypes = opts::dump::DumpIds;
    DumpBytes = opts::dump::DumpIdData;
    DumpExtras = opts::dump::DumpIdExtras;
    Indices.assign(opts::dump::DumpIdIndex.begin(),
                   opts::dump::DumpIdIndex.end());
  }

  if (!Present) {
    printStreamNotPresent(StreamIdx == StreamTPI ? "TPI" : "IPI");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Unexpected error processing types: ");

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

  auto &Types = (StreamIdx == StreamTPI) ? File.types() : File.ids();

  // Only emit notes about referenced/unreferenced for types.
  TypeReferenceTracker *MaybeTracker =
      (StreamIdx == StreamTPI) ? RefTracker.get() : nullptr;

  // Enable resolving forward decls.
  Stream.buildHashMap();

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

  if (DumpExtras) {
    P.NewLine();

    P.formatLine("Header Version: {0}",
                 static_cast<uint32_t>(Stream.getTpiVersion()));
    P.formatLine("Hash Stream Index: {0}", Stream.getTypeHashStreamIndex());
    P.formatLine("Aux Hash Stream Index: {0}",
                 Stream.getTypeHashStreamAuxIndex());
    P.formatLine("Hash Key Size: {0}", Stream.getHashKeySize());
    P.formatLine("Num Hash Buckets: {0}", Stream.getNumHashBuckets());

    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));
    }

    if (getPdb().hasPDBStringTable()) {
      P.NewLine();
      P.formatLine("Hash Adjusters:");
      auto &Adjusters = Stream.getHashAdjusters();
      auto &Strings = Err(getPdb().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();
}

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

  AutoIndent Indent(P);

  ExitOnError Err("Unexpected error processing symbols: ");

  auto &Types = File.types();

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

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

  std::unique_ptr<llvm::Error> SymbolError;

  iterateModuleSubsections<DebugSymbolsSubsectionRef>(
      File, PrintScope{P, 2},
      [&](uint32_t Modi, const SymbolGroup &Strings,
          DebugSymbolsSubsectionRef &Symbols) {
        Dumper.setSymbolGroup(&Strings);
        for (auto Symbol : Symbols) {
          if (auto EC = Visitor.visitSymbolRecord(Symbol)) {
            SymbolError = llvm::make_unique<Error>(std::move(EC));
            return;
          }
        }
      });

  if (SymbolError)
    return std::move(*SymbolError);

  return Error::success();
}

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

  if (File.isPdb() && !getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Unexpected error processing symbols: ");

  auto &Ids = File.ids();
  auto &Types = File.types();

  iterateSymbolGroups(
      File, PrintScope{P, 2}, [&](uint32_t I, const SymbolGroup &Strings) {
        auto ExpectedModS = getModuleDebugStream(File.pdb(), I);
        if (!ExpectedModS) {
          P.formatLine("Error loading module stream {0}.  {1}", I,
                       toString(ExpectedModS.takeError()));
          return;
        }

        ModuleDebugStreamRef &ModS = *ExpectedModS;

        SymbolVisitorCallbackPipeline Pipeline;
        SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
        MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Strings,
                                   Ids, 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)));
          return;
        }
      });
  return Error::success();
}

Error DumpOutputStyle::dumpTypeRefStats() {
  printHeader(P, "Type Reference Statistics");
  AutoIndent Indent(P);

  // Sum the byte size of all type records, and the size and count of all
  // referenced records.
  size_t TotalRecs = File.types().size();
  size_t RefRecs = 0;
  size_t TotalBytes = 0;
  size_t RefBytes = 0;
  auto &Types = File.types();
  for (Optional<TypeIndex> TI = Types.getFirst(); TI; TI = Types.getNext(*TI)) {
    CVType Type = File.types().getType(*TI);
    TotalBytes += Type.length();
    if (RefTracker->isTypeReferenced(*TI)) {
      ++RefRecs;
      RefBytes += Type.length();
    }
  }

  P.formatLine("Records referenced: {0:N} / {1:N} {2:P}", RefRecs, TotalRecs,
               (double)RefRecs / TotalRecs);
  P.formatLine("Bytes referenced: {0:N} / {1:N} {2:P}", RefBytes, TotalBytes,
               (double)RefBytes / TotalBytes);

  return Error::success();
}

Error DumpOutputStyle::dumpGSIRecords() {
  printHeader(P, "GSI Records");

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBSymbolStream()) {
    printStreamNotPresent("GSI Common Symbol");
    return Error::success();
  }

  AutoIndent Indent(P);

  auto &Records = cantFail(getPdb().getPDBSymbolStream());
  auto &Types = File.types();
  auto &Ids = File.ids();

  P.printLine("Records");
  SymbolVisitorCallbackPipeline Pipeline;
  SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
  MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Ids, Types);

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

  BinaryStreamRef SymStream = Records.getSymbolArray().getUnderlyingStream();
  if (auto E = Visitor.visitSymbolStream(Records.getSymbolArray(), 0))
    return E;
  return Error::success();
}

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

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBGlobalsStream()) {
    printStreamNotPresent("Globals");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Error dumping globals stream: ");
  auto &Globals = Err(getPdb().getPDBGlobalsStream());

  if (opts::dump::DumpGlobalNames.empty()) {
    const GSIHashTable &Table = Globals.getGlobalsTable();
    Err(dumpSymbolsFromGSI(Table, opts::dump::DumpGlobalExtras));
  } else {
    SymbolStream &SymRecords = cantFail(getPdb().getPDBSymbolStream());
    auto &Types = File.types();
    auto &Ids = File.ids();

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

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

    using ResultEntryType = std::pair<uint32_t, CVSymbol>;
    for (StringRef Name : opts::dump::DumpGlobalNames) {
      AutoIndent Indent(P);
      P.formatLine("Global Name `{0}`", Name);
      std::vector<ResultEntryType> Results =
          Globals.findRecordsByName(Name, SymRecords);
      if (Results.empty()) {
        AutoIndent Indent(P);
        P.printLine("(no matching records found)");
        continue;
      }

      for (ResultEntryType Result : Results) {
        if (auto E = Visitor.visitSymbolRecord(Result.second, Result.first))
          return E;
      }
    }
  }
  return Error::success();
}

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

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBPublicsStream()) {
    printStreamNotPresent("Publics");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Error dumping publics stream: ");
  auto &Publics = Err(getPdb().getPDBPublicsStream());

  const GSIHashTable &PublicsTable = Publics.getPublicsTable();
  if (opts::dump::DumpPublicExtras) {
    P.printLine("Publics Header");
    AutoIndent Indent(P);
    P.formatLine("sym hash = {0}, thunk table addr = {1}", Publics.getSymHash(),
                 formatSegmentOffset(Publics.getThunkTableSection(),
                                     Publics.getThunkTableOffset()));
  }
  Err(dumpSymbolsFromGSI(PublicsTable, opts::dump::DumpPublicExtras));

  // Skip the rest if we aren't dumping extras.
  if (!opts::dump::DumpPublicExtras)
    return Error::success();

  P.formatLine("Address Map");
  {
    // These are offsets into the publics stream sorted by secidx:secrel.
    AutoIndent Indent2(P);
    for (uint32_t Addr : Publics.getAddressMap())
      P.formatLine("off = {0}", Addr);
  }

  // The thunk map is optional debug info used for ILT thunks.
  if (!Publics.getThunkMap().empty()) {
    P.formatLine("Thunk Map");
    AutoIndent Indent2(P);
    for (uint32_t Addr : Publics.getThunkMap())
      P.formatLine("{0:x8}", Addr);
  }

  // The section offsets table appears to be empty when incremental linking
  // isn't in use.
  if (!Publics.getSectionOffsets().empty()) {
    P.formatLine("Section Offsets");
    AutoIndent Indent2(P);
    for (const SectionOffset &SO : Publics.getSectionOffsets())
      P.formatLine("{0:x4}:{1:x8}", uint16_t(SO.Isect), uint32_t(SO.Off));
  }

  return Error::success();
}

Error DumpOutputStyle::dumpSymbolsFromGSI(const GSIHashTable &Table,
                                          bool HashExtras) {
  auto ExpectedSyms = getPdb().getPDBSymbolStream();
  if (!ExpectedSyms)
    return ExpectedSyms.takeError();
  auto &Types = File.types();
  auto &Ids = File.ids();

  if (HashExtras) {
    P.printLine("GSI Header");
    AutoIndent Indent(P);
    P.formatLine("sig = {0:X}, hdr = {1:X}, hr size = {2}, num buckets = {3}",
                 Table.getVerSignature(), Table.getVerHeader(),
                 Table.getHashRecordSize(), Table.getNumBuckets());
  }

  {
    P.printLine("Records");
    SymbolVisitorCallbackPipeline Pipeline;
    SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
    MinimalSymbolDumper Dumper(P, opts::dump::DumpSymRecordBytes, Ids, Types);

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


    BinaryStreamRef SymStream =
        ExpectedSyms->getSymbolArray().getUnderlyingStream();
    for (uint32_t PubSymOff : Table) {
      Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, PubSymOff);
      if (!Sym)
        return Sym.takeError();
      if (auto E = Visitor.visitSymbolRecord(*Sym, PubSymOff))
        return E;
    }
  }

  // Return early if we aren't dumping public hash table and address map info.
  if (HashExtras) {
    P.formatLine("Hash Entries");
    {
      AutoIndent Indent2(P);
      for (const PSHashRecord &HR : Table.HashRecords)
        P.formatLine("off = {0}, refcnt = {1}", uint32_t(HR.Off),
          uint32_t(HR.CRef));
    }

    P.formatLine("Hash Buckets");
    {
      AutoIndent Indent2(P);
      for (uint32_t Hash : Table.HashBuckets)
        P.formatLine("{0:x8}", Hash);
    }
  }

  return Error::success();
}

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::dumpSectionHeaders() {
  dumpSectionHeaders("Section Headers", DbgHeaderType::SectionHdr);
  dumpSectionHeaders("Original Section Headers", DbgHeaderType::SectionHdrOrig);
  return Error::success();
}

void DumpOutputStyle::dumpSectionHeaders(StringRef Label, DbgHeaderType Type) {
  printHeader(P, Label);

  if (File.isObj()) {
    printStreamNotValidForObj();
    return;
  }

  if (!getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return;
  }

  AutoIndent Indent(P);
  ExitOnError Err("Error dumping section headers: ");
  std::unique_ptr<MappedBlockStream> Stream;
  ArrayRef<object::coff_section> Headers;
  auto ExpectedHeaders = loadSectionHeaders(getPdb(), Type);
  if (!ExpectedHeaders) {
    P.printLine(toString(ExpectedHeaders.takeError()));
    return;
  }
  std::tie(Stream, Headers) = std::move(*ExpectedHeaders);

  uint32_t I = 1;
  for (const auto &Header : Headers) {
    P.NewLine();
    P.formatLine("SECTION HEADER #{0}", I);
    P.formatLine("{0,8} name", Header.Name);
    P.formatLine("{0,8:X-} virtual size", uint32_t(Header.VirtualSize));
    P.formatLine("{0,8:X-} virtual address", uint32_t(Header.VirtualAddress));
    P.formatLine("{0,8:X-} size of raw data", uint32_t(Header.SizeOfRawData));
    P.formatLine("{0,8:X-} file pointer to raw data",
                 uint32_t(Header.PointerToRawData));
    P.formatLine("{0,8:X-} file pointer to relocation table",
                 uint32_t(Header.PointerToRelocations));
    P.formatLine("{0,8:X-} file pointer to line numbers",
                 uint32_t(Header.PointerToLinenumbers));
    P.formatLine("{0,8:X-} number of relocations",
                 uint32_t(Header.NumberOfRelocations));
    P.formatLine("{0,8:X-} number of line numbers",
                 uint32_t(Header.NumberOfLinenumbers));
    P.formatLine("{0,8:X-} flags", uint32_t(Header.Characteristics));
    AutoIndent IndentMore(P, 9);
    P.formatLine("{0}", formatSectionCharacteristics(
                            P.getIndentLevel(), Header.Characteristics, 1, ""));
    ++I;
  }
  return;
}

Error DumpOutputStyle::dumpSectionContribs() {
  printHeader(P, "Section Contributions");

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Error dumping section contributions: ");

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

  class Visitor : public ISectionContribVisitor {
  public:
    Visitor(LinePrinter &P, ArrayRef<std::string> Names) : P(P), Names(Names) {
      auto Max = std::max_element(
          Names.begin(), Names.end(),
          [](StringRef S1, StringRef S2) { return S1.size() < S2.size(); });
      MaxNameLen = (Max == Names.end() ? 0 : Max->size());
    }
    void visit(const SectionContrib &SC) override {
      dumpSectionContrib(P, SC, Names, MaxNameLen);
    }
    void visit(const SectionContrib2 &SC) override {
      dumpSectionContrib(P, SC, Names, MaxNameLen);
    }

  private:
    LinePrinter &P;
    uint32_t MaxNameLen;
    ArrayRef<std::string> Names;
  };

  std::vector<std::string> Names = getSectionNames(getPdb());
  Visitor V(P, makeArrayRef(Names));
  Dbi.visitSectionContributions(V);
  return Error::success();
}

Error DumpOutputStyle::dumpSectionMap() {
  printHeader(P, "Section Map");

  if (File.isObj()) {
    printStreamNotValidForObj();
    return Error::success();
  }

  if (!getPdb().hasPDBDbiStream()) {
    printStreamNotPresent("DBI");
    return Error::success();
  }

  AutoIndent Indent(P);
  ExitOnError Err("Error dumping section map: ");

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

  uint32_t I = 0;
  for (auto &M : Dbi.getSectionMap()) {
    P.formatLine(
        "Section {0:4} | ovl = {1}, group = {2}, frame = {3}, name = {4}", 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();
}
