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

#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ScopedPrinter.h"

#include <system_error>

using namespace llvm;
using namespace llvm::codeview;

namespace {
/// Use this private dumper implementation to keep implementation details about
/// the visitor out of SymbolDumper.h.
class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
public:
  CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,
                     ScopedPrinter &W, CPUType CPU, bool PrintRecordBytes)
      : Types(Types), ObjDelegate(ObjDelegate), W(W), CompilationCPUType(CPU),
        PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}

/// CVSymbolVisitor overrides.
#define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
  Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"

  Error visitSymbolBegin(CVSymbol &Record) override;
  Error visitSymbolEnd(CVSymbol &Record) override;
  Error visitUnknownSymbol(CVSymbol &Record) override;

  CPUType getCompilationCPUType() const { return CompilationCPUType; }

private:
  void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
                                   uint32_t RelocationOffset);
  void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
  void printTypeIndex(StringRef FieldName, TypeIndex TI);

  TypeCollection &Types;
  SymbolDumpDelegate *ObjDelegate;
  ScopedPrinter &W;

  /// Save the machine or CPU type when dumping a compile symbols.
  CPUType CompilationCPUType = CPUType::X64;

  bool PrintRecordBytes;
  bool InFunctionScope;
};
}

static StringRef getSymbolKindName(SymbolKind Kind) {
  switch (Kind) {
#define SYMBOL_RECORD(EnumName, EnumVal, Name)                                 \
  case EnumName:                                                               \
    return #Name;
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  default:
    break;
  }
  return "UnknownSym";
}

void CVSymbolDumperImpl::printLocalVariableAddrRange(
    const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
  DictScope S(W, "LocalVariableAddrRange");
  if (ObjDelegate)
    ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
                                     Range.OffsetStart);
  W.printHex("ISectStart", Range.ISectStart);
  W.printHex("Range", Range.Range);
}

void CVSymbolDumperImpl::printLocalVariableAddrGap(
    ArrayRef<LocalVariableAddrGap> Gaps) {
  for (auto &Gap : Gaps) {
    ListScope S(W, "LocalVariableAddrGap");
    W.printHex("GapStartOffset", Gap.GapStartOffset);
    W.printHex("Range", Gap.Range);
  }
}

void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
  codeview::printTypeIndex(W, FieldName, TI, Types);
}

Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
  W.startLine() << getSymbolKindName(CVR.Type);
  W.getOStream() << " {\n";
  W.indent();
  W.printEnum("Kind", unsigned(CVR.Type), getSymbolTypeNames());
  return Error::success();
}

Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {
  if (PrintRecordBytes && ObjDelegate)
    ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());

  W.unindent();
  W.startLine() << "}\n";
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
  StringRef LinkageName;
  W.printHex("PtrParent", Block.Parent);
  W.printHex("PtrEnd", Block.End);
  W.printHex("CodeSize", Block.CodeSize);
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
                                     Block.CodeOffset, &LinkageName);
  }
  W.printHex("Segment", Block.Segment);
  W.printString("BlockName", Block.Name);
  W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
  W.printString("Name", Thunk.Name);
  W.printNumber("Parent", Thunk.Parent);
  W.printNumber("End", Thunk.End);
  W.printNumber("Next", Thunk.Next);
  W.printNumber("Off", Thunk.Offset);
  W.printNumber("Seg", Thunk.Segment);
  W.printNumber("Len", Thunk.Length);
  W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           TrampolineSym &Tramp) {
  W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());
  W.printNumber("Size", Tramp.Size);
  W.printNumber("ThunkOff", Tramp.ThunkOffset);
  W.printNumber("TargetOff", Tramp.TargetOffset);
  W.printNumber("ThunkSection", Tramp.ThunkSection);
  W.printNumber("TargetSection", Tramp.TargetSection);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {
  W.printNumber("SectionNumber", Section.SectionNumber);
  W.printNumber("Alignment", Section.Alignment);
  W.printNumber("Rva", Section.Rva);
  W.printNumber("Length", Section.Length);
  W.printFlags("Characteristics", Section.Characteristics,
               getImageSectionCharacteristicNames(),
               COFF::SectionCharacteristics(0x00F00000));

  W.printString("Name", Section.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           CoffGroupSym &CoffGroup) {
  W.printNumber("Size", CoffGroup.Size);
  W.printFlags("Characteristics", CoffGroup.Characteristics,
               getImageSectionCharacteristicNames(),
               COFF::SectionCharacteristics(0x00F00000));
  W.printNumber("Offset", CoffGroup.Offset);
  W.printNumber("Segment", CoffGroup.Segment);
  W.printString("Name", CoffGroup.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           BPRelativeSym &BPRel) {
  W.printNumber("Offset", BPRel.Offset);
  printTypeIndex("Type", BPRel.Type);
  W.printString("VarName", BPRel.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           BuildInfoSym &BuildInfo) {
  printTypeIndex("BuildId", BuildInfo.BuildId);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           CallSiteInfoSym &CallSiteInfo) {
  StringRef LinkageName;
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("CodeOffset",
                                     CallSiteInfo.getRelocationOffset(),
                                     CallSiteInfo.CodeOffset, &LinkageName);
  }
  W.printHex("Segment", CallSiteInfo.Segment);
  printTypeIndex("Type", CallSiteInfo.Type);
  if (!LinkageName.empty())
    W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           EnvBlockSym &EnvBlock) {
  ListScope L(W, "Entries");
  for (auto Entry : EnvBlock.Fields) {
    W.printString(Entry);
  }
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           FileStaticSym &FileStatic) {
  printTypeIndex("Index", FileStatic.Index);
  W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
  W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
  W.printString("Name", FileStatic.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
  W.printNumber("Ordinal", Export.Ordinal);
  W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());
  W.printString("Name", Export.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           Compile2Sym &Compile2) {
  W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());
  W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());
  W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
  CompilationCPUType = Compile2.Machine;
  std::string FrontendVersion;
  {
    raw_string_ostream Out(FrontendVersion);
    Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor
        << '.' << Compile2.VersionFrontendBuild;
  }
  std::string BackendVersion;
  {
    raw_string_ostream Out(BackendVersion);
    Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor
        << '.' << Compile2.VersionBackendBuild;
  }
  W.printString("FrontendVersion", FrontendVersion);
  W.printString("BackendVersion", BackendVersion);
  W.printString("VersionName", Compile2.Version);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           Compile3Sym &Compile3) {
  W.printEnum("Language", uint8_t(Compile3.getLanguage()), getSourceLanguageNames());
  W.printFlags("Flags", uint32_t(Compile3.getFlags()),
               getCompileSym3FlagNames());
  W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
  CompilationCPUType = Compile3.Machine;
  std::string FrontendVersion;
  {
    raw_string_ostream Out(FrontendVersion);
    Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor
        << '.' << Compile3.VersionFrontendBuild << '.'
        << Compile3.VersionFrontendQFE;
  }
  std::string BackendVersion;
  {
    raw_string_ostream Out(BackendVersion);
    Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor
        << '.' << Compile3.VersionBackendBuild << '.'
        << Compile3.VersionBackendQFE;
  }
  W.printString("FrontendVersion", FrontendVersion);
  W.printString("BackendVersion", BackendVersion);
  W.printString("VersionName", Compile3.Version);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           ConstantSym &Constant) {
  printTypeIndex("Type", Constant.Type);
  W.printNumber("Value", Constant.Value);
  W.printString("Name", Constant.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
  StringRef LinkageName;
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
                                     Data.DataOffset, &LinkageName);
  }
  printTypeIndex("Type", Data.Type);
  W.printString("DisplayName", Data.Name);
  if (!LinkageName.empty())
    W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR,
    DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
  W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
  W.printNumber("Offset", DefRangeFramePointerRel.Offset);
  printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
                              DefRangeFramePointerRel.getRelocationOffset());
  printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
  W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register),
              getRegisterNames());
  W.printBoolean("HasSpilledUDTMember",
                 DefRangeRegisterRel.hasSpilledUDTMember());
  W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
  W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);
  printLocalVariableAddrRange(DefRangeRegisterRel.Range,
                              DefRangeRegisterRel.getRelocationOffset());
  printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
  W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
              getRegisterNames());
  W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
  printLocalVariableAddrRange(DefRangeRegister.Range,
                              DefRangeRegister.getRelocationOffset());
  printLocalVariableAddrGap(DefRangeRegister.Gaps);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
  W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
              getRegisterNames());
  W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
  W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
  printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
                              DefRangeSubfieldRegister.getRelocationOffset());
  printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
  if (ObjDelegate) {
    DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
    auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
    if (!ExpectedProgram) {
      consumeError(ExpectedProgram.takeError());
      return llvm::make_error<CodeViewError>(
          "String table offset outside of bounds of String Table!");
    }
    W.printString("Program", *ExpectedProgram);
  }
  W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
  printLocalVariableAddrRange(DefRangeSubfield.Range,
                              DefRangeSubfield.getRelocationOffset());
  printLocalVariableAddrGap(DefRangeSubfield.Gaps);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           DefRangeSym &DefRange) {
  if (ObjDelegate) {
    DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
    auto ExpectedProgram = Strings.getString(DefRange.Program);
    if (!ExpectedProgram) {
      consumeError(ExpectedProgram.takeError());
      return llvm::make_error<CodeViewError>(
          "String table offset outside of bounds of String Table!");
    }
    W.printString("Program", *ExpectedProgram);
  }
  printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
  printLocalVariableAddrGap(DefRange.Gaps);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           FrameCookieSym &FrameCookie) {
  StringRef LinkageName;
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("CodeOffset",
                                     FrameCookie.getRelocationOffset(),
                                     FrameCookie.CodeOffset, &LinkageName);
  }
  W.printEnum("Register", uint16_t(FrameCookie.Register), getRegisterNames());
  W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
              getFrameCookieKindNames());
  W.printHex("Flags", FrameCookie.Flags);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           FrameProcSym &FrameProc) {
  W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
  W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
  W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
  W.printHex("BytesOfCalleeSavedRegisters",
             FrameProc.BytesOfCalleeSavedRegisters);
  W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
  W.printHex("SectionIdOfExceptionHandler",
             FrameProc.SectionIdOfExceptionHandler);
  W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
               getFrameProcSymFlagNames());
  W.printEnum("LocalFramePtrReg",
              uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)),
              getRegisterNames());
  W.printEnum("ParamFramePtrReg",
              uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)),
              getRegisterNames());
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(
    CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
  StringRef LinkageName;
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("CodeOffset",
                                     HeapAllocSite.getRelocationOffset(),
                                     HeapAllocSite.CodeOffset, &LinkageName);
  }
  W.printHex("Segment", HeapAllocSite.Segment);
  W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
  printTypeIndex("Type", HeapAllocSite.Type);
  if (!LinkageName.empty())
    W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           InlineSiteSym &InlineSite) {
  W.printHex("PtrParent", InlineSite.Parent);
  W.printHex("PtrEnd", InlineSite.End);
  printTypeIndex("Inlinee", InlineSite.Inlinee);

  ListScope BinaryAnnotations(W, "BinaryAnnotations");
  for (auto &Annotation : InlineSite.annotations()) {
    switch (Annotation.OpCode) {
    case BinaryAnnotationsOpCode::Invalid:
      W.printString("(Annotation Padding)");
      break;
    case BinaryAnnotationsOpCode::CodeOffset:
    case BinaryAnnotationsOpCode::ChangeCodeOffset:
    case BinaryAnnotationsOpCode::ChangeCodeLength:
      W.printHex(Annotation.Name, Annotation.U1);
      break;
    case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
    case BinaryAnnotationsOpCode::ChangeLineEndDelta:
    case BinaryAnnotationsOpCode::ChangeRangeKind:
    case BinaryAnnotationsOpCode::ChangeColumnStart:
    case BinaryAnnotationsOpCode::ChangeColumnEnd:
      W.printNumber(Annotation.Name, Annotation.U1);
      break;
    case BinaryAnnotationsOpCode::ChangeLineOffset:
    case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
      W.printNumber(Annotation.Name, Annotation.S1);
      break;
    case BinaryAnnotationsOpCode::ChangeFile:
      if (ObjDelegate) {
        W.printHex("ChangeFile",
                   ObjDelegate->getFileNameForFileOffset(Annotation.U1),
                   Annotation.U1);
      } else {
        W.printHex("ChangeFile", Annotation.U1);
      }

      break;
    case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
      W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
                    << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
                    << "}\n";
      break;
    }
    case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
      W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
                    << W.hex(Annotation.U2)
                    << ", Length: " << W.hex(Annotation.U1) << "}\n";
      break;
    }
    }
  }
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           RegisterSym &Register) {
  printTypeIndex("Type", Register.Index);
  W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames());
  W.printString("Name", Register.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
  W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());
  W.printNumber("Seg", Public.Segment);
  W.printNumber("Off", Public.Offset);
  W.printString("Name", Public.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
  W.printNumber("SumName", ProcRef.SumName);
  W.printNumber("SymOffset", ProcRef.SymOffset);
  W.printNumber("Mod", ProcRef.Module);
  W.printString("Name", ProcRef.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
  StringRef LinkageName;
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
                                     Label.CodeOffset, &LinkageName);
  }
  W.printHex("Segment", Label.Segment);
  W.printHex("Flags", uint8_t(Label.Flags));
  W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
  W.printString("DisplayName", Label.Name);
  if (!LinkageName.empty())
    W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
  printTypeIndex("Type", Local.Type);
  W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
  W.printString("VarName", Local.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
  W.printHex("Signature", ObjName.Signature);
  W.printString("ObjectName", ObjName.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
  if (InFunctionScope)
    return llvm::make_error<CodeViewError>(
        "Visiting a ProcSym while inside function scope!");

  InFunctionScope = true;

  StringRef LinkageName;
  W.printHex("PtrParent", Proc.Parent);
  W.printHex("PtrEnd", Proc.End);
  W.printHex("PtrNext", Proc.Next);
  W.printHex("CodeSize", Proc.CodeSize);
  W.printHex("DbgStart", Proc.DbgStart);
  W.printHex("DbgEnd", Proc.DbgEnd);
  printTypeIndex("FunctionType", Proc.FunctionType);
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
                                     Proc.CodeOffset, &LinkageName);
  }
  W.printHex("Segment", Proc.Segment);
  W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
               getProcSymFlagNames());
  W.printString("DisplayName", Proc.Name);
  if (!LinkageName.empty())
    W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           ScopeEndSym &ScopeEnd) {
  InFunctionScope = false;
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
  ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
  for (auto FuncID : Caller.Indices)
    printTypeIndex("FuncID", FuncID);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           RegRelativeSym &RegRel) {
  W.printHex("Offset", RegRel.Offset);
  printTypeIndex("Type", RegRel.Type);
  W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames());
  W.printString("VarName", RegRel.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           ThreadLocalDataSym &Data) {
  StringRef LinkageName;
  if (ObjDelegate) {
    ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
                                     Data.DataOffset, &LinkageName);
  }
  printTypeIndex("Type", Data.Type);
  W.printString("DisplayName", Data.Name);
  if (!LinkageName.empty())
    W.printString("LinkageName", LinkageName);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
  printTypeIndex("Type", UDT.Type);
  W.printString("UDTName", UDT.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
                                           UsingNamespaceSym &UN) {
  W.printString("Namespace", UN.Name);
  return Error::success();
}

Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) {
  W.printNumber("Length", CVR.length());
  return Error::success();
}

Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
  SymbolVisitorCallbackPipeline Pipeline;
  SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
  CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
                            PrintRecordBytes);

  Pipeline.addCallbackToPipeline(Deserializer);
  Pipeline.addCallbackToPipeline(Dumper);
  CVSymbolVisitor Visitor(Pipeline);
  auto Err = Visitor.visitSymbolRecord(Record);
  CompilationCPUType = Dumper.getCompilationCPUType();
  return Err;
}

Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
  SymbolVisitorCallbackPipeline Pipeline;
  SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
  CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
                            PrintRecordBytes);

  Pipeline.addCallbackToPipeline(Deserializer);
  Pipeline.addCallbackToPipeline(Dumper);
  CVSymbolVisitor Visitor(Pipeline);
  auto Err = Visitor.visitSymbolStream(Symbols);
  CompilationCPUType = Dumper.getCompilationCPUType();
  return Err;
}
