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

#include "MinimalTypeDumper.h"

#include "FormatUtil.h"
#include "LinePrinter.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/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) {
  std::vector<std::string> Opts;
  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, ForwardReference, Options, "forward ref");
  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) {
  // 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}",
               formatClassOptions(P.getIndentLevel(), Class.Options));
  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}",
               formatClassOptions(P.getIndentLevel(), Union.Options));
  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));
  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::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();
}
