//===- 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;
  }

  P.NewLine();

  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());
  llvm::stable_sort(SortedStats,
                    [](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});
  llvm::stable_sort(NamespacedStatsSorted,
                    [](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);
          for (const auto &ExtraFileID : Entry.ExtraFiles) {
            P.formatLine("                   ");
            Strings.formatFromChecksumsOffset(P, ExtraFileID, 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()) {
    Expected<StringRef> NameOrErr = S.getName();
    if (!NameOrErr)
      return NameOrErr.takeError();
    StringRef SectionName = *NameOrErr;

    // .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;

    Expected<StringRef> ContentsOrErr = S.getContents();
    if (!ContentsOrErr)
      return ContentsOrErr.takeError();

    uint32_t Magic;
    BinaryStreamReader Reader(*ContentsOrErr, 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 = std::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();
}
