Skip to content

[NFC][TableGen] Refactor JSON and detailed record emitter #105770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/include/llvm/TableGen/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -2328,8 +2328,8 @@ class HasReferenceResolver final : public Resolver {
Init *resolve(Init *VarName) override;
};

void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS);
void EmitJSON(RecordKeeper &RK, raw_ostream &OS);
void EmitDetailedRecords(const RecordKeeper &RK, raw_ostream &OS);
void EmitJSON(const RecordKeeper &RK, raw_ostream &OS);

} // end namespace llvm

Expand Down
105 changes: 45 additions & 60 deletions llvm/lib/TableGen/DetailedRecordsBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,30 @@
#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;
const RecordKeeper &Records;

public:
DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}
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 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);
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
Expand All @@ -68,15 +62,21 @@ 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 << NL;
for (const auto &Var : GlobalList) {
OS << Var.first << " = " << Var.second->getAsString() << NL;
}
OS << '\n';
for (const auto &Var : GlobalList)
OS << Var.first << " = " << Var.second->getAsString() << '\n';
}

// Print the classes, including the template arguments, superclasses,
Expand All @@ -85,13 +85,12 @@ 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();
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);
printTemplateArgs(*Class, OS);
printSuperclasses(*Class, OS);
printFields(*Class, OS);
}
}

Expand All @@ -101,103 +100,89 @@ 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();
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);
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();
void DetailedRecordsEmitter::printDefms(const 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;
for (const SMLoc Loc : reverse(LocList))
OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Loc));
OS << '\n';
}

// Print the template arguments of a class.
void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,
void DetailedRecordsEmitter::printTemplateArgs(const Record &Rec,
raw_ostream &OS) {
ArrayRef<Init *> Args = Rec->getTemplateArgs();
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);
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;
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(Record *Rec, raw_ostream &OS) {
ArrayRef<std::pair<Record *, SMRange>> Superclasses = Rec->getSuperClasses();
void DetailedRecordsEmitter::printSuperclasses(const 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))
for (const auto &[ClassRec, Loc] : Superclasses) {
if (Rec.hasDirectSuperClass(ClassRec))
OS << formatv(" {0}", ClassRec->getNameInitAsString());
else
OS << formatv(" ({0})", ClassRec->getNameInitAsString());
}
OS << NL;
OS << '\n';
}

// 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();
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())) {
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) {
void llvm::EmitDetailedRecords(const RecordKeeper &RK, raw_ostream &OS) {
// Instantiate the emitter class and invoke run().
DetailedRecordsEmitter(RK).run(OS);
}

} // namespace llvm
Loading
Loading