//===- 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 "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.
  if (!Hashes) {
    P.formatLine("{0} | {1} [size = {2}]",
                 fmt_align(Index, AlignStyle::Right, Width),
                 formatTypeLeafKind(Record.Type), Record.length());
  } else {
    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.formatLine("{0} | {1} [size = {2}, hash = {3}]",
                 fmt_align(Index, AlignStyle::Right, Width),
                 formatTypeLeafKind(Record.Type), Record.length(), H);
  }
  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();
}
