//===- MinimalTypeDumper.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 "MinimalTypeDumper.h"

#include "FormatUtil.h"
#include "LinePrinter.h"
#include "TypeReferenceTracker.h"

#include "llvm-pdbutil.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"

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

static std::string formatClassOptions(uint32_t IndentLevel,
                                      ClassOptions Options, TpiStream *Stream,
                                      TypeIndex CurrentTypeIndex) {
  std::vector<std::string> Opts;

  if (Stream && Stream->supportsTypeLookup() &&
      !opts::dump::DontResolveForwardRefs &&
      ((Options & ClassOptions::ForwardReference) != ClassOptions::None)) {
    // If we're able to resolve forward references, do that.
    Expected<TypeIndex> ETI =
        Stream->findFullDeclForForwardRef(CurrentTypeIndex);
    if (!ETI) {
      consumeError(ETI.takeError());
      PUSH_FLAG(ClassOptions, ForwardReference, Options, "forward ref (??\?)");
    } else {
      const char *Direction = (*ETI == CurrentTypeIndex)
                                  ? "="
                                  : ((*ETI < CurrentTypeIndex) ? "<-" : "->");
      std::string Formatted =
          formatv("forward ref ({0} {1})", Direction, *ETI).str();
      PUSH_FLAG(ClassOptions, ForwardReference, Options, std::move(Formatted));
    }
  } else {
    PUSH_FLAG(ClassOptions, ForwardReference, Options, "forward ref");
  }

  PUSH_FLAG(ClassOptions, HasConstructorOrDestructor, Options,
            "has ctor / dtor");
  PUSH_FLAG(ClassOptions, ContainsNestedClass, Options,
            "contains nested class");
  PUSH_FLAG(ClassOptions, HasConversionOperator, Options,
            "conversion operator");
  PUSH_FLAG(ClassOptions, HasUniqueName, Options, "has unique name");
  PUSH_FLAG(ClassOptions, Intrinsic, Options, "intrin");
  PUSH_FLAG(ClassOptions, Nested, Options, "is nested");
  PUSH_FLAG(ClassOptions, HasOverloadedOperator, Options,
            "overloaded operator");
  PUSH_FLAG(ClassOptions, HasOverloadedAssignmentOperator, Options,
            "overloaded operator=");
  PUSH_FLAG(ClassOptions, Packed, Options, "packed");
  PUSH_FLAG(ClassOptions, Scoped, Options, "scoped");
  PUSH_FLAG(ClassOptions, Sealed, Options, "sealed");

  return typesetItemList(Opts, 4, IndentLevel, " | ");
}

static std::string pointerOptions(PointerOptions Options) {
  std::vector<std::string> Opts;
  PUSH_FLAG(PointerOptions, Flat32, Options, "flat32");
  PUSH_FLAG(PointerOptions, Volatile, Options, "volatile");
  PUSH_FLAG(PointerOptions, Const, Options, "const");
  PUSH_FLAG(PointerOptions, Unaligned, Options, "unaligned");
  PUSH_FLAG(PointerOptions, Restrict, Options, "restrict");
  PUSH_FLAG(PointerOptions, WinRTSmartPointer, Options, "winrt");
  if (Opts.empty())
    return "None";
  return join(Opts, " | ");
}

static std::string modifierOptions(ModifierOptions Options) {
  std::vector<std::string> Opts;
  PUSH_FLAG(ModifierOptions, Const, Options, "const");
  PUSH_FLAG(ModifierOptions, Volatile, Options, "volatile");
  PUSH_FLAG(ModifierOptions, Unaligned, Options, "unaligned");
  if (Opts.empty())
    return "None";
  return join(Opts, " | ");
}

static std::string formatCallingConvention(CallingConvention Convention) {
  switch (Convention) {
    RETURN_CASE(CallingConvention, AlphaCall, "alphacall");
    RETURN_CASE(CallingConvention, AM33Call, "am33call");
    RETURN_CASE(CallingConvention, ArmCall, "armcall");
    RETURN_CASE(CallingConvention, ClrCall, "clrcall");
    RETURN_CASE(CallingConvention, FarC, "far cdecl");
    RETURN_CASE(CallingConvention, FarFast, "far fastcall");
    RETURN_CASE(CallingConvention, FarPascal, "far pascal");
    RETURN_CASE(CallingConvention, FarStdCall, "far stdcall");
    RETURN_CASE(CallingConvention, FarSysCall, "far syscall");
    RETURN_CASE(CallingConvention, Generic, "generic");
    RETURN_CASE(CallingConvention, Inline, "inline");
    RETURN_CASE(CallingConvention, M32RCall, "m32rcall");
    RETURN_CASE(CallingConvention, MipsCall, "mipscall");
    RETURN_CASE(CallingConvention, NearC, "cdecl");
    RETURN_CASE(CallingConvention, NearFast, "fastcall");
    RETURN_CASE(CallingConvention, NearPascal, "pascal");
    RETURN_CASE(CallingConvention, NearStdCall, "stdcall");
    RETURN_CASE(CallingConvention, NearSysCall, "near syscall");
    RETURN_CASE(CallingConvention, NearVector, "vectorcall");
    RETURN_CASE(CallingConvention, PpcCall, "ppccall");
    RETURN_CASE(CallingConvention, SHCall, "shcall");
    RETURN_CASE(CallingConvention, SH5Call, "sh5call");
    RETURN_CASE(CallingConvention, ThisCall, "thiscall");
    RETURN_CASE(CallingConvention, TriCall, "tricall");
  }
  return formatUnknownEnum(Convention);
}

static std::string formatPointerMode(PointerMode Mode) {
  switch (Mode) {
    RETURN_CASE(PointerMode, LValueReference, "ref");
    RETURN_CASE(PointerMode, Pointer, "pointer");
    RETURN_CASE(PointerMode, PointerToDataMember, "data member pointer");
    RETURN_CASE(PointerMode, PointerToMemberFunction, "member fn pointer");
    RETURN_CASE(PointerMode, RValueReference, "rvalue ref");
  }
  return formatUnknownEnum(Mode);
}

static std::string memberAccess(MemberAccess Access) {
  switch (Access) {
    RETURN_CASE(MemberAccess, None, "");
    RETURN_CASE(MemberAccess, Private, "private");
    RETURN_CASE(MemberAccess, Protected, "protected");
    RETURN_CASE(MemberAccess, Public, "public");
  }
  return formatUnknownEnum(Access);
}

static std::string methodKind(MethodKind Kind) {
  switch (Kind) {
    RETURN_CASE(MethodKind, Vanilla, "");
    RETURN_CASE(MethodKind, Virtual, "virtual");
    RETURN_CASE(MethodKind, Static, "static");
    RETURN_CASE(MethodKind, Friend, "friend");
    RETURN_CASE(MethodKind, IntroducingVirtual, "intro virtual");
    RETURN_CASE(MethodKind, PureVirtual, "pure virtual");
    RETURN_CASE(MethodKind, PureIntroducingVirtual, "pure intro virtual");
  }
  return formatUnknownEnum(Kind);
}

static std::string pointerKind(PointerKind Kind) {
  switch (Kind) {
    RETURN_CASE(PointerKind, Near16, "ptr16");
    RETURN_CASE(PointerKind, Far16, "far ptr16");
    RETURN_CASE(PointerKind, Huge16, "huge ptr16");
    RETURN_CASE(PointerKind, BasedOnSegment, "segment based");
    RETURN_CASE(PointerKind, BasedOnValue, "value based");
    RETURN_CASE(PointerKind, BasedOnSegmentValue, "segment value based");
    RETURN_CASE(PointerKind, BasedOnAddress, "address based");
    RETURN_CASE(PointerKind, BasedOnSegmentAddress, "segment address based");
    RETURN_CASE(PointerKind, BasedOnType, "type based");
    RETURN_CASE(PointerKind, BasedOnSelf, "self based");
    RETURN_CASE(PointerKind, Near32, "ptr32");
    RETURN_CASE(PointerKind, Far32, "far ptr32");
    RETURN_CASE(PointerKind, Near64, "ptr64");
  }
  return formatUnknownEnum(Kind);
}

static std::string memberAttributes(const MemberAttributes &Attrs) {
  std::vector<std::string> Opts;
  std::string Access = memberAccess(Attrs.getAccess());
  std::string Kind = methodKind(Attrs.getMethodKind());
  if (!Access.empty())
    Opts.push_back(Access);
  if (!Kind.empty())
    Opts.push_back(Kind);
  MethodOptions Flags = Attrs.getFlags();
  PUSH_FLAG(MethodOptions, Pseudo, Flags, "pseudo");
  PUSH_FLAG(MethodOptions, NoInherit, Flags, "noinherit");
  PUSH_FLAG(MethodOptions, NoConstruct, Flags, "noconstruct");
  PUSH_FLAG(MethodOptions, CompilerGenerated, Flags, "compiler-generated");
  PUSH_FLAG(MethodOptions, Sealed, Flags, "sealed");
  return join(Opts, " ");
}

static std::string formatPointerAttrs(const PointerRecord &Record) {
  PointerMode Mode = Record.getMode();
  PointerOptions Opts = Record.getOptions();
  PointerKind Kind = Record.getPointerKind();
  return formatv("mode = {0}, opts = {1}, kind = {2}", formatPointerMode(Mode),
                 pointerOptions(Opts), pointerKind(Kind));
}

static std::string formatFunctionOptions(FunctionOptions Options) {
  std::vector<std::string> Opts;

  PUSH_FLAG(FunctionOptions, CxxReturnUdt, Options, "returns cxx udt");
  PUSH_FLAG(FunctionOptions, ConstructorWithVirtualBases, Options,
            "constructor with virtual bases");
  PUSH_FLAG(FunctionOptions, Constructor, Options, "constructor");
  if (Opts.empty())
    return "None";
  return join(Opts, " | ");
}

Error MinimalTypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
  CurrentTypeIndex = Index;
  // formatLine puts the newline at the beginning, so we use formatLine here
  // to start a new line, and then individual visit methods use format to
  // append to the existing line.
  P.formatLine("{0} | {1} [size = {2}",
               fmt_align(Index, AlignStyle::Right, Width),
               formatTypeLeafKind(Record.Type), Record.length());
  if (Hashes) {
    std::string H;
    if (Index.toArrayIndex() >= HashValues.size()) {
      H = "(not present)";
    } else {
      uint32_t Hash = HashValues[Index.toArrayIndex()];
      Expected<uint32_t> MaybeHash = hashTypeRecord(Record);
      if (!MaybeHash)
        return MaybeHash.takeError();
      uint32_t OurHash = *MaybeHash;
      OurHash %= NumHashBuckets;
      if (Hash == OurHash)
        H = "0x" + utohexstr(Hash);
      else
        H = "0x" + utohexstr(Hash) + ", our hash = 0x" + utohexstr(OurHash);
    }
    P.format(", hash = {0}", H);
  }
  if (RefTracker) {
    if (RefTracker->isTypeReferenced(Index))
      P.format(", referenced");
    else
      P.format(", unreferenced");
  }
  P.format("]");
  P.Indent(Width + 3);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitTypeEnd(CVType &Record) {
  P.Unindent(Width + 3);
  if (RecordBytes) {
    AutoIndent Indent(P, 9);
    P.formatBinary("Bytes", Record.RecordData, 0);
  }
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitMemberBegin(CVMemberRecord &Record) {
  P.formatLine("- {0}", formatTypeLeafKind(Record.Kind));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitMemberEnd(CVMemberRecord &Record) {
  if (RecordBytes) {
    AutoIndent Indent(P, 2);
    P.formatBinary("Bytes", Record.Data, 0);
  }
  return Error::success();
}

StringRef MinimalTypeDumpVisitor::getTypeName(TypeIndex TI) const {
  if (TI.isNoneType())
    return "";
  return Types.getTypeName(TI);
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               FieldListRecord &FieldList) {
  if (auto EC = codeview::visitMemberRecordStream(FieldList.Data, *this))
    return EC;

  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               StringIdRecord &String) {
  P.format(" ID: {0}, String: {1}", String.getId(), String.getString());
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               ArgListRecord &Args) {
  auto Indices = Args.getIndices();
  if (Indices.empty())
    return Error::success();

  auto Max = std::max_element(Indices.begin(), Indices.end());
  uint32_t W = NumDigits(Max->getIndex()) + 2;

  for (auto I : Indices)
    P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
                 getTypeName(I));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               StringListRecord &Strings) {
  auto Indices = Strings.getIndices();
  if (Indices.empty())
    return Error::success();

  auto Max = std::max_element(Indices.begin(), Indices.end());
  uint32_t W = NumDigits(Max->getIndex()) + 2;

  for (auto I : Indices)
    P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
                 getTypeName(I));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               ClassRecord &Class) {
  P.format(" `{0}`", Class.Name);
  if (Class.hasUniqueName())
    P.formatLine("unique name: `{0}`", Class.UniqueName);
  P.formatLine("vtable: {0}, base list: {1}, field list: {2}",
               Class.VTableShape, Class.DerivationList, Class.FieldList);
  P.formatLine("options: {0}, sizeof {1}",
               formatClassOptions(P.getIndentLevel(), Class.Options, Stream,
                                  CurrentTypeIndex),
               Class.Size);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               UnionRecord &Union) {
  P.format(" `{0}`", Union.Name);
  if (Union.hasUniqueName())
    P.formatLine("unique name: `{0}`", Union.UniqueName);
  P.formatLine("field list: {0}", Union.FieldList);
  P.formatLine("options: {0}, sizeof {1}",
               formatClassOptions(P.getIndentLevel(), Union.Options, Stream,
                                  CurrentTypeIndex),
               Union.Size);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
  P.format(" `{0}`", Enum.Name);
  if (Enum.hasUniqueName())
    P.formatLine("unique name: `{0}`", Enum.UniqueName);
  P.formatLine("field list: {0}, underlying type: {1}", Enum.FieldList,
               Enum.UnderlyingType);
  P.formatLine("options: {0}",
               formatClassOptions(P.getIndentLevel(), Enum.Options, Stream,
                                  CurrentTypeIndex));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
  if (AT.Name.empty()) {
    P.formatLine("size: {0}, index type: {1}, element type: {2}", AT.Size,
                 AT.IndexType, AT.ElementType);
  } else {
    P.formatLine("name: {0}, size: {1}, index type: {2}, element type: {3}",
                 AT.Name, AT.Size, AT.IndexType, AT.ElementType);
  }
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               VFTableRecord &VFT) {
  P.formatLine("offset: {0}, complete class: {1}, overridden vftable: {2}",
               VFT.VFPtrOffset, VFT.CompleteClass, VFT.OverriddenVFTable);
  P.formatLine("method names: ");
  if (!VFT.MethodNames.empty()) {
    std::string Sep =
        formatv("\n{0}",
                fmt_repeat(' ', P.getIndentLevel() + strlen("method names: ")))
            .str();
    P.print(join(VFT.MethodNames, Sep));
  }
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               MemberFuncIdRecord &Id) {
  P.formatLine("name = {0}, type = {1}, class type = {2}", Id.Name,
               Id.FunctionType, Id.ClassType);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               ProcedureRecord &Proc) {
  P.formatLine("return type = {0}, # args = {1}, param list = {2}",
               Proc.ReturnType, Proc.ParameterCount, Proc.ArgumentList);
  P.formatLine("calling conv = {0}, options = {1}",
               formatCallingConvention(Proc.CallConv),
               formatFunctionOptions(Proc.Options));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               MemberFunctionRecord &MF) {
  P.formatLine("return type = {0}, # args = {1}, param list = {2}",
               MF.ReturnType, MF.ParameterCount, MF.ArgumentList);
  P.formatLine("class type = {0}, this type = {1}, this adjust = {2}",
               MF.ClassType, MF.ThisType, MF.ThisPointerAdjustment);
  P.formatLine("calling conv = {0}, options = {1}",
               formatCallingConvention(MF.CallConv),
               formatFunctionOptions(MF.Options));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               FuncIdRecord &Func) {
  P.formatLine("name = {0}, type = {1}, parent scope = {2}", Func.Name,
               Func.FunctionType, Func.ParentScope);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               TypeServer2Record &TS) {
  P.formatLine("name = {0}, age = {1}, guid = {2}", TS.Name, TS.Age, TS.Guid);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               PointerRecord &Ptr) {
  P.formatLine("referent = {0}, {1}", Ptr.ReferentType,
               formatPointerAttrs(Ptr));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               ModifierRecord &Mod) {
  P.formatLine("referent = {0}, modifiers = {1}", Mod.ModifiedType,
               modifierOptions(Mod.Modifiers));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               VFTableShapeRecord &Shape) {
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               UdtModSourceLineRecord &U) {
  P.formatLine("udt = {0}, mod = {1}, file = {2}, line = {3}", U.UDT, U.Module,
               U.SourceFile.getIndex(), U.LineNumber);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               UdtSourceLineRecord &U) {
  P.formatLine("udt = {0}, file = {1}, line = {2}", U.UDT,
               U.SourceFile.getIndex(), U.LineNumber);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               BitFieldRecord &BF) {
  P.formatLine("type = {0}, bit offset = {1}, # bits = {2}", BF.Type,
               BF.BitOffset, BF.BitSize);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(
    CVType &CVR, MethodOverloadListRecord &Overloads) {
  for (auto &M : Overloads.Methods)
    P.formatLine("- Method [type = {0}, vftable offset = {1}, attrs = {2}]",
                 M.Type, M.VFTableOffset, memberAttributes(M.Attrs));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               BuildInfoRecord &BI) {
  auto Indices = BI.ArgIndices;
  if (Indices.empty())
    return Error::success();

  auto Max = std::max_element(Indices.begin(), Indices.end());
  uint32_t W = NumDigits(Max->getIndex()) + 2;

  for (auto I : Indices)
    P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
                 getTypeName(I));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &R) {
  std::string Type = (R.Mode == LabelType::Far) ? "far" : "near";
  P.format(" type = {0}", Type);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               PrecompRecord &Precomp) {
  P.format(" start index = {0:X+}, types count = {1:X+}, signature = {2:X+},"
           " precomp path = {3}",
           Precomp.StartTypeIndex, Precomp.TypesCount, Precomp.Signature,
           Precomp.PrecompFilePath);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
                                               EndPrecompRecord &EP) {
  P.format(" signature = {0:X+}", EP.Signature);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               NestedTypeRecord &Nested) {
  P.format(" [name = `{0}`, parent = {1}]", Nested.Name, Nested.Type);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               OneMethodRecord &Method) {
  P.format(" [name = `{0}`]", Method.Name);
  AutoIndent Indent(P);
  P.formatLine("type = {0}, vftable offset = {1}, attrs = {2}", Method.Type,
               Method.VFTableOffset, memberAttributes(Method.Attrs));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               OverloadedMethodRecord &Method) {
  P.format(" [name = `{0}`, # overloads = {1}, overload list = {2}]",
           Method.Name, Method.NumOverloads, Method.MethodList);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               DataMemberRecord &Field) {
  P.format(" [name = `{0}`, Type = {1}, offset = {2}, attrs = {3}]", Field.Name,
           Field.Type, Field.FieldOffset, memberAttributes(Field.Attrs));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               StaticDataMemberRecord &Field) {
  P.format(" [name = `{0}`, type = {1}, attrs = {2}]", Field.Name, Field.Type,
           memberAttributes(Field.Attrs));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               EnumeratorRecord &Enum) {
  P.format(" [{0} = {1}]", Enum.Name,
           Enum.Value.toString(10, Enum.Value.isSigned()));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               BaseClassRecord &Base) {
  AutoIndent Indent(P);
  P.formatLine("type = {0}, offset = {1}, attrs = {2}", Base.Type, Base.Offset,
               memberAttributes(Base.Attrs));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               VirtualBaseClassRecord &Base) {
  AutoIndent Indent(P);
  P.formatLine(
      "base = {0}, vbptr = {1}, vbptr offset = {2}, vtable index = {3}",
      Base.BaseType, Base.VBPtrType, Base.VBPtrOffset, Base.VTableIndex);
  P.formatLine("attrs = {0}", memberAttributes(Base.Attrs));
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               ListContinuationRecord &Cont) {
  P.format(" continuation = {0}", Cont.ContinuationIndex);
  return Error::success();
}

Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
                                               VFPtrRecord &VFP) {
  P.format(" type = {0}", VFP.Type);
  return Error::success();
}
