Path: blob/main/contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp
35234 views
//===- DetailedRecordBackend.cpp - Detailed Records Report -*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This Tablegen backend prints a report that includes all the global9// variables, classes, and records in complete detail. It includes more10// detail than the default TableGen printer backend.11//12//===----------------------------------------------------------------------===//1314#include "llvm/ADT/ArrayRef.h"15#include "llvm/ADT/StringRef.h"16#include "llvm/Support/ErrorHandling.h"17#include "llvm/Support/FormatVariadic.h"18#include "llvm/Support/SMLoc.h"19#include "llvm/Support/SourceMgr.h"20#include "llvm/Support/raw_ostream.h"21#include "llvm/TableGen/Error.h"22#include "llvm/TableGen/Record.h"23#include <map>24#include <memory>25#include <string>26#include <utility>2728#define DEBUG_TYPE "detailed-records-backend"2930#define NL "\n"3132using namespace llvm;3334namespace {3536class DetailedRecordsEmitter {37private:38RecordKeeper &Records;3940public:41DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}4243void run(raw_ostream &OS);44void printReportHeading(raw_ostream &OS);45void printVariables(raw_ostream &OS);46void printClasses(raw_ostream &OS);47void printRecords(raw_ostream &OS);48void printSectionHeading(StringRef Title, int Count, raw_ostream &OS);49void printDefms(Record *Rec, raw_ostream &OS);50void printTemplateArgs(Record *Rec, raw_ostream &OS);51void printSuperclasses(Record *Rec, raw_ostream &OS);52void printFields(Record *Rec, raw_ostream &OS);53}; // emitter class5455} // anonymous namespace5657// Print the report.58void DetailedRecordsEmitter::run(raw_ostream &OS) {59printReportHeading(OS);60printVariables(OS);61printClasses(OS);62printRecords(OS);63}6465// Print the report heading, including the source file name.66void DetailedRecordsEmitter::printReportHeading(raw_ostream &OS) {67OS << formatv("DETAILED RECORDS for file {0}\n", Records.getInputFilename());68}6970// Print the global variables.71void DetailedRecordsEmitter::printVariables(raw_ostream &OS) {72const auto GlobalList = Records.getGlobals();73printSectionHeading("Global Variables", GlobalList.size(), OS);7475OS << NL;76for (const auto &Var : GlobalList) {77OS << Var.first << " = " << Var.second->getAsString() << NL;78}79}8081// Print the classes, including the template arguments, superclasses,82// and fields.83void DetailedRecordsEmitter::printClasses(raw_ostream &OS) {84const auto &ClassList = Records.getClasses();85printSectionHeading("Classes", ClassList.size(), OS);8687for (const auto &ClassPair : ClassList) {88auto *const Class = ClassPair.second.get();89OS << formatv("\n{0} |{1}|\n", Class->getNameInitAsString(),90SrcMgr.getFormattedLocationNoOffset(Class->getLoc().front()));91printTemplateArgs(Class, OS);92printSuperclasses(Class, OS);93printFields(Class, OS);94}95}9697// Print the records, including the defm sequences, supercasses,98// and fields.99void DetailedRecordsEmitter::printRecords(raw_ostream &OS) {100const auto &RecordList = Records.getDefs();101printSectionHeading("Records", RecordList.size(), OS);102103for (const auto &RecPair : RecordList) {104auto *const Rec = RecPair.second.get();105std::string Name = Rec->getNameInitAsString();106OS << formatv("\n{0} |{1}|\n", Name.empty() ? "\"\"" : Name,107SrcMgr.getFormattedLocationNoOffset(Rec->getLoc().front()));108printDefms(Rec, OS);109printSuperclasses(Rec, OS);110printFields(Rec, OS);111}112}113114// Print a section heading with the name of the section and115// the item count.116void DetailedRecordsEmitter::printSectionHeading(StringRef Title, int Count,117raw_ostream &OS) {118OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);119}120121// Print the record's defm source locations, if any. Note that they122// are stored in the reverse order of their invocation.123void DetailedRecordsEmitter::printDefms(Record *Rec, raw_ostream &OS) {124const auto &LocList = Rec->getLoc();125if (LocList.size() < 2)126return;127128OS << " Defm sequence:";129for (unsigned I = LocList.size() - 1; I >= 1; --I) {130OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(LocList[I]));131}132OS << NL;133}134135// Print the template arguments of a class.136void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,137raw_ostream &OS) {138ArrayRef<Init *> Args = Rec->getTemplateArgs();139if (Args.empty()) {140OS << " Template args: (none)\n";141return;142}143144OS << " Template args:\n";145for (const Init *ArgName : Args) {146const RecordVal *Value = Rec->getValue(ArgName);147assert(Value && "Template argument value not found.");148OS << " ";149Value->print(OS, false);150OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));151OS << NL;152}153}154155// Print the superclasses of a class or record. Indirect superclasses156// are enclosed in parentheses.157void DetailedRecordsEmitter::printSuperclasses(Record *Rec, raw_ostream &OS) {158ArrayRef<std::pair<Record *, SMRange>> Superclasses = Rec->getSuperClasses();159if (Superclasses.empty()) {160OS << " Superclasses: (none)\n";161return;162}163164OS << " Superclasses:";165for (const auto &SuperclassPair : Superclasses) {166auto *ClassRec = SuperclassPair.first;167if (Rec->hasDirectSuperClass(ClassRec))168OS << formatv(" {0}", ClassRec->getNameInitAsString());169else170OS << formatv(" ({0})", ClassRec->getNameInitAsString());171}172OS << NL;173}174175// Print the fields of a class or record, including their source locations.176void DetailedRecordsEmitter::printFields(Record *Rec, raw_ostream &OS) {177const auto &ValueList = Rec->getValues();178if (ValueList.empty()) {179OS << " Fields: (none)\n";180return;181}182183OS << " Fields:\n";184for (const RecordVal &Value : ValueList)185if (!Rec->isTemplateArg(Value.getNameInit())) {186OS << " ";187Value.print(OS, false);188OS << formatv(" |{0}|\n",189SrcMgr.getFormattedLocationNoOffset(Value.getLoc()));190}191}192193namespace llvm {194195// This function is called by TableGen after parsing the files.196197void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS) {198// Instantiate the emitter class and invoke run().199DetailedRecordsEmitter(RK).run(OS);200}201202} // namespace llvm203204205