123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- //===- 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 <map>
- #include <memory>
- #include <string>
- #include <utility>
- #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(StringRef 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(StringRef 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
|