aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp b/contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp
new file mode 100644
index 000000000000..2c3c3358b347
--- /dev/null
+++ b/contrib/llvm-project/llvm/lib/TableGen/DetailedRecordsBackend.cpp
@@ -0,0 +1,203 @@
+//===- 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();
+ OS << formatv("\n{0} |{1}|\n", Rec->getNameInitAsString(),
+ 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