//===- TypeRecordMapping.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 "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
#include "llvm/Support/MD5.h"

using namespace llvm;
using namespace llvm::codeview;

namespace {

#define error(X)                                                               \
  if (auto EC = X)                                                             \
    return EC;

static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
#define CV_TYPE(enum, val) {#enum, enum},
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
};

static StringRef getLeafTypeName(TypeLeafKind LT) {
  switch (LT) {
#define TYPE_RECORD(ename, value, name)                                        \
  case ename:                                                                  \
    return #name;
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
  default:
    break;
  }
  return "UnknownLeaf";
}

template <typename T>
static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
  return lhs.Name < rhs.Name;
}

template <typename T, typename TFlag>
static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
                                ArrayRef<EnumEntry<TFlag>> Flags) {
  if (!IO.isStreaming())
    return std::string("");
  typedef EnumEntry<TFlag> FlagEntry;
  typedef SmallVector<FlagEntry, 10> FlagVector;
  FlagVector SetFlags;
  for (const auto &Flag : Flags) {
    if (Flag.Value == 0)
      continue;
    if ((Value & Flag.Value) == Flag.Value) {
      SetFlags.push_back(Flag);
    }
  }

  llvm::sort(SetFlags, &compEnumNames<TFlag>);

  std::string FlagLabel;
  bool FirstOcc = true;
  for (const auto &Flag : SetFlags) {
    if (FirstOcc)
      FirstOcc = false;
    else
      FlagLabel += (" | ");

    FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
  }

  if (!FlagLabel.empty()) {
    std::string LabelWithBraces(" ( ");
    LabelWithBraces += FlagLabel + " )";
    return LabelWithBraces;
  } else
    return FlagLabel;
}

template <typename T, typename TEnum>
static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
                             ArrayRef<EnumEntry<TEnum>> EnumValues) {
  if (!IO.isStreaming())
    return "";
  StringRef Name;
  for (const auto &EnumItem : EnumValues) {
    if (EnumItem.Value == Value) {
      Name = EnumItem.Name;
      break;
    }
  }

  return Name;
}

static std::string getMemberAttributes(CodeViewRecordIO &IO,
                                       MemberAccess Access, MethodKind Kind,
                                       MethodOptions Options) {
  if (!IO.isStreaming())
    return "";
  std::string AccessSpecifier = std::string(
      getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())));
  std::string MemberAttrs(AccessSpecifier);
  if (Kind != MethodKind::Vanilla) {
    std::string MethodKind = std::string(
        getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())));
    MemberAttrs += ", " + MethodKind;
  }
  if (Options != MethodOptions::None) {
    std::string MethodOptions = getFlagNames(
        IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
    MemberAttrs += ", " + MethodOptions;
  }
  return MemberAttrs;
}

struct MapOneMethodRecord {
  explicit MapOneMethodRecord(bool IsFromOverloadList)
      : IsFromOverloadList(IsFromOverloadList) {}

  Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
    std::string Attrs = getMemberAttributes(
        IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
    error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
    if (IsFromOverloadList) {
      uint16_t Padding = 0;
      error(IO.mapInteger(Padding));
    }
    error(IO.mapInteger(Method.Type, "Type"));
    if (Method.isIntroducingVirtual()) {
      error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset"));
    } else if (IO.isReading())
      Method.VFTableOffset = -1;

    if (!IsFromOverloadList)
      error(IO.mapStringZ(Method.Name, "Name"));

    return Error::success();
  }

private:
  bool IsFromOverloadList;
};
} // namespace

// Computes a string representation of a hash of the specified name, suitable
// for use when emitting CodeView type names.
static void computeHashString(StringRef Name,
                              SmallString<32> &StringifiedHash) {
  llvm::MD5 Hash;
  llvm::MD5::MD5Result Result;
  Hash.update(Name);
  Hash.final(Result);
  Hash.stringifyResult(Result, StringifiedHash);
}

static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
                                  StringRef &UniqueName, bool HasUniqueName) {
  if (IO.isWriting()) {
    // Try to be smart about what we write here.  We can't write anything too
    // large, so if we're going to go over the limit, replace lengthy names with
    // a stringified hash value.
    size_t BytesLeft = IO.maxFieldLength();
    if (HasUniqueName) {
      size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
      if (BytesNeeded > BytesLeft) {
        // The minimum space required for emitting hashes of both names.
        assert(BytesLeft >= 70);

        // Replace the entire unique name with a hash of the unique name.
        SmallString<32> Hash;
        computeHashString(UniqueName, Hash);
        std::string UniqueB = Twine("??@" + Hash + "@").str();
        assert(UniqueB.size() == 36);

        // Truncate the name if necessary and append a hash of the name.
        // The name length, hash included, is limited to 4096 bytes.
        const size_t MaxTakeN = 4096;
        size_t TakeN = std::min(MaxTakeN, BytesLeft - UniqueB.size() - 2) - 32;
        computeHashString(Name, Hash);
        std::string NameB = (Name.take_front(TakeN) + Hash).str();

        StringRef N = NameB;
        StringRef U = UniqueB;
        error(IO.mapStringZ(N));
        error(IO.mapStringZ(U));
      } else {
        error(IO.mapStringZ(Name));
        error(IO.mapStringZ(UniqueName));
      }
    } else {
      // Cap the length of the string at however many bytes we have available,
      // plus one for the required null terminator.
      auto N = StringRef(Name).take_front(BytesLeft - 1);
      error(IO.mapStringZ(N));
    }
  } else {
    // Reading & Streaming mode come after writing mode is executed for each
    // record. Truncating large names are done during writing, so its not
    // necessary to do it while reading or streaming.
    error(IO.mapStringZ(Name, "Name"));
    if (HasUniqueName)
      error(IO.mapStringZ(UniqueName, "LinkageName"));
  }

  return Error::success();
}

Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
  assert(!TypeKind.hasValue() && "Already in a type mapping!");
  assert(!MemberKind.hasValue() && "Already in a member mapping!");

  // FieldList and MethodList records can be any length because they can be
  // split with continuation records.  All other record types cannot be
  // longer than the maximum record length.
  Optional<uint32_t> MaxLen;
  if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
      CVR.kind() != TypeLeafKind::LF_METHODLIST)
    MaxLen = MaxRecordLength - sizeof(RecordPrefix);
  error(IO.beginRecord(MaxLen));
  TypeKind = CVR.kind();

  if (IO.isStreaming()) {
    auto RecordKind = CVR.kind();
    uint16_t RecordLen = CVR.length() - 2;
    std::string RecordKindName = std::string(
        getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)));
    error(IO.mapInteger(RecordLen, "Record length"));
    error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
  }
  return Error::success();
}

Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) {
  if (IO.isStreaming())
    IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
                      utohexstr(Index.getIndex()) + ")");
  return visitTypeBegin(CVR);
}

Error TypeRecordMapping::visitTypeEnd(CVType &Record) {
  assert(TypeKind.hasValue() && "Not in a type mapping!");
  assert(!MemberKind.hasValue() && "Still in a member mapping!");

  error(IO.endRecord());

  TypeKind.reset();
  return Error::success();
}

Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
  assert(TypeKind.hasValue() && "Not in a type mapping!");
  assert(!MemberKind.hasValue() && "Already in a member mapping!");

  // The largest possible subrecord is one in which there is a record prefix,
  // followed by the subrecord, followed by a continuation, and that entire
  // sequence spawns `MaxRecordLength` bytes.  So the record's length is
  // calculated as follows.

  constexpr uint32_t ContinuationLength = 8;
  error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) -
                       ContinuationLength));

  MemberKind = Record.Kind;
  if (IO.isStreaming()) {
    std::string MemberKindName = std::string(getLeafTypeName(Record.Kind));
    MemberKindName +=
        " ( " +
        (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
            .str() +
        " )";
    error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
  }
  return Error::success();
}

Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) {
  assert(TypeKind.hasValue() && "Not in a type mapping!");
  assert(MemberKind.hasValue() && "Not in a member mapping!");

  if (IO.isReading()) {
    if (auto EC = IO.skipPadding())
      return EC;
  }

  MemberKind.reset();
  error(IO.endRecord());
  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) {
  std::string ModifierNames =
      getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
                   makeArrayRef(getTypeModifierNames()));
  error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
  error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          ProcedureRecord &Record) {
  std::string CallingConvName = std::string(getEnumName(
      IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
  std::string FuncOptionNames =
      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
                   makeArrayRef(getFunctionOptionEnum()));
  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          MemberFunctionRecord &Record) {
  std::string CallingConvName = std::string(getEnumName(
      IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
  std::string FuncOptionNames =
      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
                   makeArrayRef(getFunctionOptionEnum()));
  error(IO.mapInteger(Record.ReturnType, "ReturnType"));
  error(IO.mapInteger(Record.ClassType, "ClassType"));
  error(IO.mapInteger(Record.ThisType, "ThisType"));
  error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
  error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
  error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
  error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
  error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArgListRecord &Record) {
  error(IO.mapVectorN<uint32_t>(
      Record.ArgIndices,
      [](CodeViewRecordIO &IO, TypeIndex &N) {
        return IO.mapInteger(N, "Argument");
      },
      "NumArgs"));
  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          StringListRecord &Record) {
  error(IO.mapVectorN<uint32_t>(
      Record.StringIndices,
      [](CodeViewRecordIO &IO, TypeIndex &N) {
        return IO.mapInteger(N, "Strings");
      },
      "NumStrings"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {

  SmallString<128> Attr("Attrs: ");

  if (IO.isStreaming()) {
    std::string PtrType =
        std::string(getEnumName(IO, unsigned(Record.getPointerKind()),
                                makeArrayRef(getPtrKindNames())));
    Attr += "[ Type: " + PtrType;

    std::string PtrMode = std::string(getEnumName(
        IO, unsigned(Record.getMode()), makeArrayRef(getPtrModeNames())));
    Attr += ", Mode: " + PtrMode;

    auto PtrSizeOf = Record.getSize();
    Attr += ", SizeOf: " + itostr(PtrSizeOf);

    if (Record.isFlat())
      Attr += ", isFlat";
    if (Record.isConst())
      Attr += ", isConst";
    if (Record.isVolatile())
      Attr += ", isVolatile";
    if (Record.isUnaligned())
      Attr += ", isUnaligned";
    if (Record.isRestrict())
      Attr += ", isRestricted";
    if (Record.isLValueReferenceThisPtr())
      Attr += ", isThisPtr&";
    if (Record.isRValueReferenceThisPtr())
      Attr += ", isThisPtr&&";
    Attr += " ]";
  }

  error(IO.mapInteger(Record.ReferentType, "PointeeType"));
  error(IO.mapInteger(Record.Attrs, Attr));

  if (Record.isPointerToMember()) {
    if (IO.isReading())
      Record.MemberInfo.emplace();

    MemberPointerInfo &M = *Record.MemberInfo;
    error(IO.mapInteger(M.ContainingType, "ClassType"));
    std::string PtrMemberGetRepresentation = std::string(getEnumName(
        IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())));
    error(IO.mapEnum(M.Representation,
                     "Representation: " + PtrMemberGetRepresentation));
  }

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) {
  error(IO.mapInteger(Record.ElementType, "ElementType"));
  error(IO.mapInteger(Record.IndexType, "IndexType"));
  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) {
  assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) ||
         (CVR.kind() == TypeLeafKind::LF_CLASS) ||
         (CVR.kind() == TypeLeafKind::LF_INTERFACE));

  std::string PropertiesNames =
      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
                   makeArrayRef(getClassOptionNames()));
  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
  error(IO.mapInteger(Record.FieldList, "FieldList"));
  error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
  error(IO.mapInteger(Record.VTableShape, "VShape"));
  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
                             Record.hasUniqueName()));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
  std::string PropertiesNames =
      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
                   makeArrayRef(getClassOptionNames()));
  error(IO.mapInteger(Record.MemberCount, "MemberCount"));
  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
  error(IO.mapInteger(Record.FieldList, "FieldList"));
  error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
                             Record.hasUniqueName()));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
  std::string PropertiesNames =
      getFlagNames(IO, static_cast<uint16_t>(Record.Options),
                   makeArrayRef(getClassOptionNames()));
  error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
  error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
  error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
  error(IO.mapInteger(Record.FieldList, "FieldListType"));
  error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
                             Record.hasUniqueName()));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) {
  error(IO.mapInteger(Record.Type, "Type"));
  error(IO.mapInteger(Record.BitSize, "BitSize"));
  error(IO.mapInteger(Record.BitOffset, "BitOffset"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          VFTableShapeRecord &Record) {
  uint16_t Size;
  if (!IO.isReading()) {
    ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
    Size = Slots.size();
    error(IO.mapInteger(Size, "VFEntryCount"));

    for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) {
      uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4;
      if ((SlotIndex + 1) < Slots.size()) {
        Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
      }
      error(IO.mapInteger(Byte));
    }
  } else {
    error(IO.mapInteger(Size));
    for (uint16_t I = 0; I < Size; I += 2) {
      uint8_t Byte;
      error(IO.mapInteger(Byte));
      Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
      if ((I + 1) < Size)
        Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
    }
  }

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableRecord &Record) {
  error(IO.mapInteger(Record.CompleteClass, "CompleteClass"));
  error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable"));
  error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset"));
  uint32_t NamesLen = 0;
  if (!IO.isReading()) {
    for (auto Name : Record.MethodNames)
      NamesLen += Name.size() + 1;
  }
  error(IO.mapInteger(NamesLen));
  error(IO.mapVectorTail(
      Record.MethodNames,
      [](CodeViewRecordIO &IO, StringRef &S) {
        return IO.mapStringZ(S, "MethodName");
      },
      "VFTableName"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringIdRecord &Record) {
  error(IO.mapInteger(Record.Id, "Id"));
  error(IO.mapStringZ(Record.String, "StringData"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          UdtSourceLineRecord &Record) {
  error(IO.mapInteger(Record.UDT, "UDT"));
  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
  error(IO.mapInteger(Record.LineNumber, "LineNumber"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          UdtModSourceLineRecord &Record) {
  error(IO.mapInteger(Record.UDT, "UDT"));
  error(IO.mapInteger(Record.SourceFile, "SourceFile"));
  error(IO.mapInteger(Record.LineNumber, "LineNumber"));
  error(IO.mapInteger(Record.Module, "Module"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, FuncIdRecord &Record) {
  error(IO.mapInteger(Record.ParentScope, "ParentScope"));
  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          MemberFuncIdRecord &Record) {
  error(IO.mapInteger(Record.ClassType, "ClassType"));
  error(IO.mapInteger(Record.FunctionType, "FunctionType"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          BuildInfoRecord &Record) {
  error(IO.mapVectorN<uint16_t>(
      Record.ArgIndices,
      [](CodeViewRecordIO &IO, TypeIndex &N) {
        return IO.mapInteger(N, "Argument");
      },
      "NumArgs"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          MethodOverloadListRecord &Record) {
  // TODO: Split the list into multiple records if it's longer than 64KB, using
  // a subrecord of TypeRecordKind::Index to chain the records together.
  error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true), "Method"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          FieldListRecord &Record) {
  if (IO.isStreaming()) {
    if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
      return EC;
  } else
    error(IO.mapByteVectorTail(Record.Data));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          TypeServer2Record &Record) {
  error(IO.mapGuid(Record.Guid, "Guid"));
  error(IO.mapInteger(Record.Age, "Age"));
  error(IO.mapStringZ(Record.Name, "Name"));
  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) {
  std::string ModeName = std::string(
      getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())));
  error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          BaseClassRecord &Record) {
  std::string Attrs = getMemberAttributes(
      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
  error(IO.mapInteger(Record.Type, "BaseType"));
  error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          EnumeratorRecord &Record) {
  std::string Attrs = getMemberAttributes(
      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));

  // FIXME: Handle full APInt such as __int128.
  error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          DataMemberRecord &Record) {
  std::string Attrs = getMemberAttributes(
      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
  error(IO.mapInteger(Record.Type, "Type"));
  error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          OverloadedMethodRecord &Record) {
  error(IO.mapInteger(Record.NumOverloads, "MethodCount"));
  error(IO.mapInteger(Record.MethodList, "MethodListIndex"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          OneMethodRecord &Record) {
  const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
  MapOneMethodRecord Mapper(IsFromOverloadList);
  return Mapper(IO, Record);
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          NestedTypeRecord &Record) {
  uint16_t Padding = 0;
  error(IO.mapInteger(Padding, "Padding"));
  error(IO.mapInteger(Record.Type, "Type"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          StaticDataMemberRecord &Record) {

  std::string Attrs = getMemberAttributes(
      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
  error(IO.mapInteger(Record.Type, "Type"));
  error(IO.mapStringZ(Record.Name, "Name"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          VirtualBaseClassRecord &Record) {

  std::string Attrs = getMemberAttributes(
      IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
  error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
  error(IO.mapInteger(Record.BaseType, "BaseType"));
  error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
  error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
  error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          VFPtrRecord &Record) {
  uint16_t Padding = 0;
  error(IO.mapInteger(Padding, "Padding"));
  error(IO.mapInteger(Record.Type, "Type"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
                                          ListContinuationRecord &Record) {
  uint16_t Padding = 0;
  error(IO.mapInteger(Padding, "Padding"));
  error(IO.mapInteger(Record.ContinuationIndex, "ContinuationIndex"));

  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          PrecompRecord &Precomp) {
  error(IO.mapInteger(Precomp.StartTypeIndex, "StartIndex"));
  error(IO.mapInteger(Precomp.TypesCount, "Count"));
  error(IO.mapInteger(Precomp.Signature, "Signature"));
  error(IO.mapStringZ(Precomp.PrecompFilePath, "PrecompFile"));
  return Error::success();
}

Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
                                          EndPrecompRecord &EndPrecomp) {
  error(IO.mapInteger(EndPrecomp.Signature, "Signature"));
  return Error::success();
}
