//===- 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/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include <string>

using namespace llvm;

namespace {

class DetailedRecordsEmitter {
private:
  const RecordKeeper &Records;

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

  void run(raw_ostream &OS);
  void printReportHeading(raw_ostream &OS);
  void printSectionHeading(StringRef Title, int Count, raw_ostream &OS);
  void printVariables(raw_ostream &OS);
  void printClasses(raw_ostream &OS);
  void printRecords(raw_ostream &OS);
  void printAllocationStats(raw_ostream &OS);
  void printDefms(const Record &Rec, raw_ostream &OS);
  void printTemplateArgs(const Record &Rec, raw_ostream &OS);
  void printSuperclasses(const Record &Rec, raw_ostream &OS);
  void printFields(const 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);
  printAllocationStats(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 a section heading with the name of the section and the item count.
void DetailedRecordsEmitter::printSectionHeading(StringRef Title, int Count,
                                                 raw_ostream &OS) {
  OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);
}

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

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

// Print 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 &[Name, Class] : ClassList) {
    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 &[DefName, Rec] : RecordList) {
    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 memory allocation related stats.
void DetailedRecordsEmitter::printAllocationStats(raw_ostream &OS) {
  OS << formatv("\n{0} Memory Allocation Stats {0}\n", "--------------------");
  Records.dumpAllocationStats(OS);
}

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

  OS << "  Defm sequence:";
  for (const SMLoc Loc : reverse(LocList))
    OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Loc));
  OS << '\n';
}

// Print the template arguments of a class.
void DetailedRecordsEmitter::printTemplateArgs(const Record &Rec,
                                               raw_ostream &OS) {
  ArrayRef<const 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}|\n",
                  SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));
  }
}

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

  OS << "  Superclasses:";
  for (const Record *ClassRec : Superclasses) {
    if (Rec.hasDirectSuperClass(ClassRec))
      OS << formatv(" {0}", ClassRec->getNameInitAsString());
    else
      OS << formatv(" ({0})", ClassRec->getNameInitAsString());
  }
  OS << '\n';
}

// Print the fields of a class or record, including their source locations.
void DetailedRecordsEmitter::printFields(const 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()));
    }
}

// This function is called by TableGen after parsing the files.
void llvm::EmitDetailedRecords(const RecordKeeper &RK, raw_ostream &OS) {
  // Instantiate the emitter class and invoke run().
  DetailedRecordsEmitter(RK).run(OS);
}
