//===- DetailedRecordBackend.cpp - Detailed Records Report      -*- 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
//
//===----------------------------------------------------------------------===//
//
// This Tablegen backend prints a report that includes all the global 
// variables, classes, and records in complete detail. It includes more
// detail than the default TableGen printer backend.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <set>
#include <string>
#include <vector>

#define DEBUG_TYPE "detailed-records-backend"

#define NL "\n"

using namespace llvm;

namespace {

class DetailedRecordsEmitter {
private:
  RecordKeeper &Records;

public:
  DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}

  void run(raw_ostream &OS);
  void printReportHeading(raw_ostream &OS);
  void printVariables(raw_ostream &OS);
  void printClasses(raw_ostream &OS);
  void printRecords(raw_ostream &OS);
  void printSectionHeading(std::string Title, int Count, raw_ostream &OS);
  void printDefms(Record *Rec, raw_ostream &OS);
  void printTemplateArgs(Record *Rec, raw_ostream &OS);
  void printSuperclasses(Record *Rec, raw_ostream &OS);
  void printFields(Record *Rec, raw_ostream &OS);
}; // emitter class

} // anonymous namespace

// Print the report.
void DetailedRecordsEmitter::run(raw_ostream &OS) {
  printReportHeading(OS);
  printVariables(OS);
  printClasses(OS);
  printRecords(OS);
}

// Print the report heading, including the source file name.
void DetailedRecordsEmitter::printReportHeading(raw_ostream &OS) {
  OS << formatv("DETAILED RECORDS for file {0}\n", Records.getInputFilename());
}

// Print the global variables.
void DetailedRecordsEmitter::printVariables(raw_ostream &OS) {
  const auto GlobalList = Records.getGlobals();
  printSectionHeading("Global Variables", GlobalList.size(), OS);

  OS << NL;
  for (const auto &Var : GlobalList) {
    OS << Var.first << " = " << Var.second->getAsString() << NL;
  }
}

// Print the classes, including the template arguments, superclasses,
// and fields.
void DetailedRecordsEmitter::printClasses(raw_ostream &OS) {
  const auto &ClassList = Records.getClasses();
  printSectionHeading("Classes", ClassList.size(), OS);

  for (const auto &ClassPair : ClassList) {
    auto *const Class = ClassPair.second.get();
    OS << formatv("\n{0}  |{1}|\n", Class->getNameInitAsString(),
                  SrcMgr.getFormattedLocationNoOffset(Class->getLoc().front()));
    printTemplateArgs(Class, OS);
    printSuperclasses(Class, OS);
    printFields(Class, OS);
  }
}

// Print the records, including the defm sequences, supercasses,
// and fields.
void DetailedRecordsEmitter::printRecords(raw_ostream &OS) {
  const auto &RecordList = Records.getDefs();
  printSectionHeading("Records", RecordList.size(), OS);

  for (const auto &RecPair : RecordList) {
    auto *const Rec = RecPair.second.get();
    std::string Name = Rec->getNameInitAsString();
    OS << formatv("\n{0}  |{1}|\n", Name.empty() ? "\"\"" : Name,
                  SrcMgr.getFormattedLocationNoOffset(Rec->getLoc().front()));
    printDefms(Rec, OS);
    printSuperclasses(Rec, OS);
    printFields(Rec, OS);
  }
}

// Print a section heading with the name of the section and
// the item count.
void DetailedRecordsEmitter::printSectionHeading(std::string Title, int Count,
                                                 raw_ostream &OS) {
  OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);
}

// Print the record's defm source locations, if any. Note that they
// are stored in the reverse order of their invocation.
void DetailedRecordsEmitter::printDefms(Record *Rec, raw_ostream &OS) {
  const auto &LocList = Rec->getLoc();
  if (LocList.size() < 2)
    return;

  OS << "  Defm sequence:";
  for (unsigned I = LocList.size() - 1; I >= 1; --I) {
    OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(LocList[I]));
  }
  OS << NL;
}

// Print the template arguments of a class.
void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,
                                               raw_ostream &OS) {
  ArrayRef<Init *> Args = Rec->getTemplateArgs();
  if (Args.empty()) {
    OS << "  Template args: (none)\n";
    return;
  }

  OS << "  Template args:\n";
  for (const Init *ArgName : Args) {
    const RecordVal *Value = Rec->getValue(ArgName);
    assert(Value && "Template argument value not found.");
    OS << "    ";
    Value->print(OS, false);
    OS << formatv("  |{0}|", SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));
    OS << NL;
  }
}

// Print the superclasses of a class or record. Indirect superclasses
// are enclosed in parentheses.
void DetailedRecordsEmitter::printSuperclasses(Record *Rec, raw_ostream &OS) {
  ArrayRef<std::pair<Record *, SMRange>> Superclasses = Rec->getSuperClasses();
  if (Superclasses.empty()) {
    OS << "  Superclasses: (none)\n";
    return;
  }

  OS << "  Superclasses:";
  for (const auto &SuperclassPair : Superclasses) {
    auto *ClassRec = SuperclassPair.first;
    if (Rec->hasDirectSuperClass(ClassRec))
      OS << formatv(" {0}", ClassRec->getNameInitAsString());
    else
      OS << formatv(" ({0})", ClassRec->getNameInitAsString());
  }
  OS << NL;
}

// Print the fields of a class or record, including their source locations.
void DetailedRecordsEmitter::printFields(Record *Rec, raw_ostream &OS) {
  const auto &ValueList = Rec->getValues();
  if (ValueList.empty()) {
    OS << "  Fields: (none)\n";
    return;
  }

  OS << "  Fields:\n";
  for (const RecordVal &Value : ValueList)
    if (!Rec->isTemplateArg(Value.getNameInit())) {
      OS << "    ";
      Value.print(OS, false);
      OS << formatv("  |{0}|\n",
                    SrcMgr.getFormattedLocationNoOffset(Value.getLoc()));
    }
}

namespace llvm {

// This function is called by TableGen after parsing the files.

void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS) {
  // Instantiate the emitter class and invoke run().
  DetailedRecordsEmitter(RK).run(OS);
}

} // namespace llvm
