//===- PrettyTypeDumper.cpp - PDBSymDumper type dumper *------------ 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 "PrettyTypeDumper.h"

#include "LinePrinter.h"
#include "PrettyBuiltinDumper.h"
#include "PrettyClassDefinitionDumper.h"
#include "PrettyEnumDumper.h"
#include "PrettyFunctionDumper.h"
#include "PrettyTypedefDumper.h"
#include "llvm-pdbutil.h"

#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "llvm/DebugInfo/PDB/UDTLayout.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/FormatVariadic.h"

using namespace llvm;
using namespace llvm::pdb;

using LayoutPtr = std::unique_ptr<ClassLayout>;

typedef bool (*CompareFunc)(const LayoutPtr &S1, const LayoutPtr &S2);

static bool CompareNames(const LayoutPtr &S1, const LayoutPtr &S2) {
  return S1->getName() < S2->getName();
}

static bool CompareSizes(const LayoutPtr &S1, const LayoutPtr &S2) {
  return S1->getSize() < S2->getSize();
}

static bool ComparePadding(const LayoutPtr &S1, const LayoutPtr &S2) {
  return S1->deepPaddingSize() < S2->deepPaddingSize();
}

static bool ComparePaddingPct(const LayoutPtr &S1, const LayoutPtr &S2) {
  double Pct1 = (double)S1->deepPaddingSize() / (double)S1->getSize();
  double Pct2 = (double)S2->deepPaddingSize() / (double)S2->getSize();
  return Pct1 < Pct2;
}

static bool ComparePaddingImmediate(const LayoutPtr &S1, const LayoutPtr &S2) {
  return S1->immediatePadding() < S2->immediatePadding();
}

static bool ComparePaddingPctImmediate(const LayoutPtr &S1,
                                       const LayoutPtr &S2) {
  double Pct1 = (double)S1->immediatePadding() / (double)S1->getSize();
  double Pct2 = (double)S2->immediatePadding() / (double)S2->getSize();
  return Pct1 < Pct2;
}

static CompareFunc getComparisonFunc(opts::pretty::ClassSortMode Mode) {
  switch (Mode) {
  case opts::pretty::ClassSortMode::Name:
    return CompareNames;
  case opts::pretty::ClassSortMode::Size:
    return CompareSizes;
  case opts::pretty::ClassSortMode::Padding:
    return ComparePadding;
  case opts::pretty::ClassSortMode::PaddingPct:
    return ComparePaddingPct;
  case opts::pretty::ClassSortMode::PaddingImmediate:
    return ComparePaddingImmediate;
  case opts::pretty::ClassSortMode::PaddingPctImmediate:
    return ComparePaddingPctImmediate;
  default:
    return nullptr;
  }
}

template <typename Enumerator>
static std::vector<std::unique_ptr<ClassLayout>>
filterAndSortClassDefs(LinePrinter &Printer, Enumerator &E,
                       uint32_t UnfilteredCount) {
  std::vector<std::unique_ptr<ClassLayout>> Filtered;

  Filtered.reserve(UnfilteredCount);
  CompareFunc Comp = getComparisonFunc(opts::pretty::ClassOrder);

  if (UnfilteredCount > 10000) {
    errs() << formatv("Filtering and sorting {0} types", UnfilteredCount);
    errs().flush();
  }
  uint32_t Examined = 0;
  uint32_t Discarded = 0;
  while (auto Class = E.getNext()) {
    ++Examined;
    if (Examined % 10000 == 0) {
      errs() << formatv("Examined {0}/{1} items.  {2} items discarded\n",
                        Examined, UnfilteredCount, Discarded);
      errs().flush();
    }

    if (Class->getUnmodifiedTypeId() != 0) {
      ++Discarded;
      continue;
    }

    if (Printer.IsTypeExcluded(Class->getName(), Class->getLength())) {
      ++Discarded;
      continue;
    }

    auto Layout = llvm::make_unique<ClassLayout>(std::move(Class));
    if (Layout->deepPaddingSize() < opts::pretty::PaddingThreshold) {
      ++Discarded;
      continue;
    }
    if (Layout->immediatePadding() < opts::pretty::ImmediatePaddingThreshold) {
      ++Discarded;
      continue;
    }

    Filtered.push_back(std::move(Layout));
  }

  if (Comp)
    llvm::sort(Filtered, Comp);
  return Filtered;
}

TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {}

template <typename T>
static bool isTypeExcluded(LinePrinter &Printer, const T &Symbol) {
  return false;
}

static bool isTypeExcluded(LinePrinter &Printer,
                           const PDBSymbolTypeEnum &Enum) {
  if (Printer.IsTypeExcluded(Enum.getName(), Enum.getLength()))
    return true;
  // Dump member enums when dumping their class definition.
  if (nullptr != Enum.getClassParent())
    return true;
  return false;
}

static bool isTypeExcluded(LinePrinter &Printer,
                           const PDBSymbolTypeTypedef &Typedef) {
  return Printer.IsTypeExcluded(Typedef.getName(), Typedef.getLength());
}

template <typename SymbolT>
static void dumpSymbolCategory(LinePrinter &Printer, const PDBSymbolExe &Exe,
                               TypeDumper &TD, StringRef Label) {
  if (auto Children = Exe.findAllChildren<SymbolT>()) {
    Printer.NewLine();
    WithColor(Printer, PDB_ColorItem::Identifier).get() << Label;
    Printer << ": (" << Children->getChildCount() << " items)";
    Printer.Indent();
    while (auto Child = Children->getNext()) {
      if (isTypeExcluded(Printer, *Child))
        continue;

      Printer.NewLine();
      Child->dump(TD);
    }
    Printer.Unindent();
  }
}

static void printClassDecl(LinePrinter &Printer,
                           const PDBSymbolTypeUDT &Class) {
  if (Class.getUnmodifiedTypeId() != 0) {
    if (Class.isConstType())
      WithColor(Printer, PDB_ColorItem::Keyword).get() << "const ";
    if (Class.isVolatileType())
      WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
    if (Class.isUnalignedType())
      WithColor(Printer, PDB_ColorItem::Keyword).get() << "unaligned ";
  }
  WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
  WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
}

void TypeDumper::start(const PDBSymbolExe &Exe) {
  if (opts::pretty::Enums)
    dumpSymbolCategory<PDBSymbolTypeEnum>(Printer, Exe, *this, "Enums");

  if (opts::pretty::Funcsigs)
    dumpSymbolCategory<PDBSymbolTypeFunctionSig>(Printer, Exe, *this,
                                                 "Function Signatures");

  if (opts::pretty::Typedefs)
    dumpSymbolCategory<PDBSymbolTypeTypedef>(Printer, Exe, *this, "Typedefs");

  if (opts::pretty::Arrays)
    dumpSymbolCategory<PDBSymbolTypeArray>(Printer, Exe, *this, "Arrays");

  if (opts::pretty::Pointers)
    dumpSymbolCategory<PDBSymbolTypePointer>(Printer, Exe, *this, "Pointers");

  if (opts::pretty::VTShapes)
    dumpSymbolCategory<PDBSymbolTypeVTableShape>(Printer, Exe, *this,
                                                 "VFTable Shapes");

  if (opts::pretty::Classes) {
    if (auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>()) {
      uint32_t All = Classes->getChildCount();

      Printer.NewLine();
      WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";

      bool Precompute = false;
      Precompute =
          (opts::pretty::ClassOrder != opts::pretty::ClassSortMode::None);

      // If we're using no sort mode, then we can start getting immediate output
      // from the tool by just filtering as we go, rather than processing
      // everything up front so that we can sort it.  This makes the tool more
      // responsive.  So only precompute the filtered/sorted set of classes if
      // necessary due to the specified options.
      std::vector<LayoutPtr> Filtered;
      uint32_t Shown = All;
      if (Precompute) {
        Filtered = filterAndSortClassDefs(Printer, *Classes, All);

        Shown = Filtered.size();
      }

      Printer << ": (Showing " << Shown << " items";
      if (Shown < All)
        Printer << ", " << (All - Shown) << " filtered";
      Printer << ")";
      Printer.Indent();

      // If we pre-computed, iterate the filtered/sorted list, otherwise iterate
      // the DIA enumerator and filter on the fly.
      if (Precompute) {
        for (auto &Class : Filtered)
          dumpClassLayout(*Class);
      } else {
        while (auto Class = Classes->getNext()) {
          if (Printer.IsTypeExcluded(Class->getName(), Class->getLength()))
            continue;

          // No point duplicating a full class layout.  Just print the modified
          // declaration and continue.
          if (Class->getUnmodifiedTypeId() != 0) {
            Printer.NewLine();
            printClassDecl(Printer, *Class);
            continue;
          }

          auto Layout = llvm::make_unique<ClassLayout>(std::move(Class));
          if (Layout->deepPaddingSize() < opts::pretty::PaddingThreshold)
            continue;

          dumpClassLayout(*Layout);
        }
      }

      Printer.Unindent();
    }
  }
}

void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) {
  assert(opts::pretty::Enums);

  EnumDumper Dumper(Printer);
  Dumper.start(Symbol);
}

void TypeDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
  BuiltinDumper BD(Printer);
  BD.start(Symbol);
}

void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) {
  printClassDecl(Printer, Symbol);
}

void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
  assert(opts::pretty::Typedefs);

  TypedefDumper Dumper(Printer);
  Dumper.start(Symbol);
}

void TypeDumper::dump(const PDBSymbolTypeArray &Symbol) {
  auto ElementType = Symbol.getElementType();

  ElementType->dump(*this);
  Printer << "[";
  WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Symbol.getCount();
  Printer << "]";
}

void TypeDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
  FunctionDumper Dumper(Printer);
  Dumper.start(Symbol, nullptr, FunctionDumper::PointerType::None);
}

void TypeDumper::dump(const PDBSymbolTypePointer &Symbol) {
  std::unique_ptr<PDBSymbol> P = Symbol.getPointeeType();

  if (auto *FS = dyn_cast<PDBSymbolTypeFunctionSig>(P.get())) {
    FunctionDumper Dumper(Printer);
    FunctionDumper::PointerType PT =
        Symbol.isReference() ? FunctionDumper::PointerType::Reference
                             : FunctionDumper::PointerType::Pointer;
    Dumper.start(*FS, nullptr, PT);
    return;
  }

  if (auto *UDT = dyn_cast<PDBSymbolTypeUDT>(P.get())) {
    printClassDecl(Printer, *UDT);
  } else if (P) {
    P->dump(*this);
  }

  if (auto Parent = Symbol.getClassParent()) {
    auto UDT = llvm::unique_dyn_cast<PDBSymbolTypeUDT>(std::move(Parent));
    if (UDT)
      Printer << " " << UDT->getName() << "::";
  }

  if (Symbol.isReference())
    Printer << "&";
  else if (Symbol.isRValueReference())
    Printer << "&&";
  else
    Printer << "*";
}

void TypeDumper::dump(const PDBSymbolTypeVTableShape &Symbol) {
  Printer.format("<vtshape ({0} methods)>", Symbol.getCount());
}

void TypeDumper::dumpClassLayout(const ClassLayout &Class) {
  assert(opts::pretty::Classes);

  if (opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::None) {
    WithColor(Printer, PDB_ColorItem::Keyword).get()
        << Class.getClass().getUdtKind() << " ";
    WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
  } else {
    ClassDefinitionDumper Dumper(Printer);
    Dumper.start(Class);
  }
}
