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

#include "PrettyCompilandDumper.h"

#include "LinePrinter.h"
#include "PrettyFunctionDumper.h"
#include "llvm-pdbutil.h"

#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
#include "llvm/DebugInfo/PDB/PDBSymbol.h"
#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <utility>

using namespace llvm;
using namespace llvm::pdb;

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

void CompilandDumper::dump(const PDBSymbolCompilandDetails &Symbol) {}

void CompilandDumper::dump(const PDBSymbolCompilandEnv &Symbol) {}

void CompilandDumper::start(const PDBSymbolCompiland &Symbol,
                            CompilandDumpFlags opts) {
  std::string FullName = Symbol.getName();
  if (Printer.IsCompilandExcluded(FullName))
    return;

  Printer.NewLine();
  WithColor(Printer, PDB_ColorItem::Path).get() << FullName;

  if (opts & Flags::Lines) {
    const IPDBSession &Session = Symbol.getSession();
    auto Files = Session.getSourceFilesForCompiland(Symbol);
    Printer.Indent();
    while (auto File = Files->getNext()) {
      Printer.NewLine();
      WithColor(Printer, PDB_ColorItem::Path).get() << File->getFileName();

      auto Lines = Session.findLineNumbers(Symbol, *File);
      Printer.Indent();
      while (auto Line = Lines->getNext()) {
        Printer.NewLine();
        uint32_t LineStart = Line->getLineNumber();
        uint32_t LineEnd = Line->getLineNumberEnd();

        Printer << "Line ";
        PDB_ColorItem StatementColor = Line->isStatement()
                                           ? PDB_ColorItem::Keyword
                                           : PDB_ColorItem::LiteralValue;
        WithColor(Printer, StatementColor).get() << LineStart;
        if (LineStart != LineEnd)
          WithColor(Printer, StatementColor).get() << " - " << LineEnd;

        uint32_t ColumnStart = Line->getColumnNumber();
        uint32_t ColumnEnd = Line->getColumnNumberEnd();
        if (ColumnStart != 0 || ColumnEnd != 0) {
          Printer << ", Column: ";
          WithColor(Printer, StatementColor).get() << ColumnStart;
          if (ColumnEnd != ColumnStart)
            WithColor(Printer, StatementColor).get() << " - " << ColumnEnd;
        }

        Printer << ", Address: ";
        if (Line->getLength() > 0) {
          uint64_t AddrStart = Line->getVirtualAddress();
          uint64_t AddrEnd = AddrStart + Line->getLength() - 1;
          WithColor(Printer, PDB_ColorItem::Address).get()
              << "[" << format_hex(AddrStart, 10) << " - "
              << format_hex(AddrEnd, 10) << "]";
          Printer << " (" << Line->getLength() << " bytes)";
        } else {
          uint64_t AddrStart = Line->getVirtualAddress();
          WithColor(Printer, PDB_ColorItem::Address).get()
              << "[" << format_hex(AddrStart, 10) << "] ";
          Printer << "(0 bytes)";
        }
      }
      Printer.Unindent();
    }
    Printer.Unindent();
  }

  if (opts & Flags::Children) {
    auto ChildrenEnum = Symbol.findAllChildren();
    Printer.Indent();
    while (auto Child = ChildrenEnum->getNext())
      Child->dump(*this);
    Printer.Unindent();
  }
}

void CompilandDumper::dump(const PDBSymbolData &Symbol) {
  if (!shouldDumpSymLevel(opts::pretty::SymLevel::Data))
    return;
  if (Printer.IsSymbolExcluded(Symbol.getName()))
    return;

  Printer.NewLine();

  switch (auto LocType = Symbol.getLocationType()) {
  case PDB_LocType::Static:
    Printer << "data: ";
    WithColor(Printer, PDB_ColorItem::Address).get()
        << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "]";

    WithColor(Printer, PDB_ColorItem::Comment).get()
        << " [sizeof = " << getTypeLength(Symbol) << "]";

    break;
  case PDB_LocType::Constant:
    Printer << "constant: ";
    WithColor(Printer, PDB_ColorItem::LiteralValue).get()
        << "[" << Symbol.getValue() << "]";
    WithColor(Printer, PDB_ColorItem::Comment).get()
        << " [sizeof = " << getTypeLength(Symbol) << "]";
    break;
  default:
    Printer << "data(unexpected type=" << LocType << ")";
  }

  Printer << " ";
  WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
}

void CompilandDumper::dump(const PDBSymbolFunc &Symbol) {
  if (!shouldDumpSymLevel(opts::pretty::SymLevel::Functions))
    return;
  if (Symbol.getLength() == 0)
    return;
  if (Printer.IsSymbolExcluded(Symbol.getName()))
    return;

  Printer.NewLine();
  FunctionDumper Dumper(Printer);
  Dumper.start(Symbol, FunctionDumper::PointerType::None);
}

void CompilandDumper::dump(const PDBSymbolLabel &Symbol) {
  if (Printer.IsSymbolExcluded(Symbol.getName()))
    return;

  Printer.NewLine();
  Printer << "label ";
  WithColor(Printer, PDB_ColorItem::Address).get()
      << "[" << format_hex(Symbol.getVirtualAddress(), 10) << "] ";
  WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
}

void CompilandDumper::dump(const PDBSymbolThunk &Symbol) {
  if (!shouldDumpSymLevel(opts::pretty::SymLevel::Thunks))
    return;
  if (Printer.IsSymbolExcluded(Symbol.getName()))
    return;

  Printer.NewLine();
  Printer << "thunk ";
  codeview::ThunkOrdinal Ordinal = Symbol.getThunkOrdinal();
  uint64_t VA = Symbol.getVirtualAddress();
  if (Ordinal == codeview::ThunkOrdinal::TrampIncremental) {
    uint64_t Target = Symbol.getTargetVirtualAddress();
    WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(VA, 10);
    Printer << " -> ";
    WithColor(Printer, PDB_ColorItem::Address).get() << format_hex(Target, 10);
  } else {
    WithColor(Printer, PDB_ColorItem::Address).get()
        << "[" << format_hex(VA, 10) << " - "
        << format_hex(VA + Symbol.getLength(), 10) << "]";
  }
  Printer << " (";
  WithColor(Printer, PDB_ColorItem::Register).get() << Ordinal;
  Printer << ") ";
  std::string Name = Symbol.getName();
  if (!Name.empty())
    WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
}

void CompilandDumper::dump(const PDBSymbolTypeTypedef &Symbol) {}

void CompilandDumper::dump(const PDBSymbolUnknown &Symbol) {
  Printer.NewLine();
  Printer << "unknown (" << Symbol.getSymTag() << ")";
}
