LLVM  14.0.0git
DetailedRecordsBackend.cpp
Go to the documentation of this file.
1 //===- DetailedRecordBackend.cpp - Detailed Records Report -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This Tablegen backend prints a report that includes all the global
10 // variables, classes, and records in complete detail. It includes more
11 // detail than the default TableGen printer backend.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Format.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/TableGen/Error.h"
23 #include "llvm/TableGen/Record.h"
25 #include <string>
26 #include <utility>
27 
28 #define DEBUG_TYPE "detailed-records-backend"
29 
30 #define NL "\n"
31 
32 using namespace llvm;
33 
34 namespace {
35 
36 class DetailedRecordsEmitter {
37 private:
38  RecordKeeper &Records;
39 
40 public:
41  DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}
42 
43  void run(raw_ostream &OS);
44  void printReportHeading(raw_ostream &OS);
45  void printVariables(raw_ostream &OS);
46  void printClasses(raw_ostream &OS);
47  void printRecords(raw_ostream &OS);
48  void printSectionHeading(StringRef Title, int Count, raw_ostream &OS);
49  void printDefms(Record *Rec, raw_ostream &OS);
50  void printTemplateArgs(Record *Rec, raw_ostream &OS);
51  void printSuperclasses(Record *Rec, raw_ostream &OS);
52  void printFields(Record *Rec, raw_ostream &OS);
53 }; // emitter class
54 
55 } // anonymous namespace
56 
57 // Print the report.
58 void DetailedRecordsEmitter::run(raw_ostream &OS) {
59  printReportHeading(OS);
60  printVariables(OS);
61  printClasses(OS);
62  printRecords(OS);
63 }
64 
65 // Print the report heading, including the source file name.
66 void DetailedRecordsEmitter::printReportHeading(raw_ostream &OS) {
67  OS << formatv("DETAILED RECORDS for file {0}\n", Records.getInputFilename());
68 }
69 
70 // Print the global variables.
71 void DetailedRecordsEmitter::printVariables(raw_ostream &OS) {
72  const auto GlobalList = Records.getGlobals();
73  printSectionHeading("Global Variables", GlobalList.size(), OS);
74 
75  OS << NL;
76  for (const auto &Var : GlobalList) {
77  OS << Var.first << " = " << Var.second->getAsString() << NL;
78  }
79 }
80 
81 // Print the classes, including the template arguments, superclasses,
82 // and fields.
83 void DetailedRecordsEmitter::printClasses(raw_ostream &OS) {
84  const auto &ClassList = Records.getClasses();
85  printSectionHeading("Classes", ClassList.size(), OS);
86 
87  for (const auto &ClassPair : ClassList) {
88  auto *const Class = ClassPair.second.get();
89  OS << formatv("\n{0} |{1}|\n", Class->getNameInitAsString(),
90  SrcMgr.getFormattedLocationNoOffset(Class->getLoc().front()));
91  printTemplateArgs(Class, OS);
92  printSuperclasses(Class, OS);
93  printFields(Class, OS);
94  }
95 }
96 
97 // Print the records, including the defm sequences, supercasses,
98 // and fields.
99 void DetailedRecordsEmitter::printRecords(raw_ostream &OS) {
100  const auto &RecordList = Records.getDefs();
101  printSectionHeading("Records", RecordList.size(), OS);
102 
103  for (const auto &RecPair : RecordList) {
104  auto *const Rec = RecPair.second.get();
105  std::string Name = Rec->getNameInitAsString();
106  OS << formatv("\n{0} |{1}|\n", Name.empty() ? "\"\"" : Name,
107  SrcMgr.getFormattedLocationNoOffset(Rec->getLoc().front()));
108  printDefms(Rec, OS);
109  printSuperclasses(Rec, OS);
110  printFields(Rec, OS);
111  }
112 }
113 
114 // Print a section heading with the name of the section and
115 // the item count.
116 void DetailedRecordsEmitter::printSectionHeading(StringRef Title, int Count,
117  raw_ostream &OS) {
118  OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);
119 }
120 
121 // Print the record's defm source locations, if any. Note that they
122 // are stored in the reverse order of their invocation.
123 void DetailedRecordsEmitter::printDefms(Record *Rec, raw_ostream &OS) {
124  const auto &LocList = Rec->getLoc();
125  if (LocList.size() < 2)
126  return;
127 
128  OS << " Defm sequence:";
129  for (unsigned I = LocList.size() - 1; I >= 1; --I) {
130  OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(LocList[I]));
131  }
132  OS << NL;
133 }
134 
135 // Print the template arguments of a class.
136 void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,
137  raw_ostream &OS) {
139  if (Args.empty()) {
140  OS << " Template args: (none)\n";
141  return;
142  }
143 
144  OS << " Template args:\n";
145  for (const Init *ArgName : Args) {
146  const RecordVal *Value = Rec->getValue(ArgName);
147  assert(Value && "Template argument value not found.");
148  OS << " ";
149  Value->print(OS, false);
150  OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));
151  OS << NL;
152  }
153 }
154 
155 // Print the superclasses of a class or record. Indirect superclasses
156 // are enclosed in parentheses.
157 void DetailedRecordsEmitter::printSuperclasses(Record *Rec, raw_ostream &OS) {
159  if (Superclasses.empty()) {
160  OS << " Superclasses: (none)\n";
161  return;
162  }
163 
164  OS << " Superclasses:";
165  for (const auto &SuperclassPair : Superclasses) {
166  auto *ClassRec = SuperclassPair.first;
167  if (Rec->hasDirectSuperClass(ClassRec))
168  OS << formatv(" {0}", ClassRec->getNameInitAsString());
169  else
170  OS << formatv(" ({0})", ClassRec->getNameInitAsString());
171  }
172  OS << NL;
173 }
174 
175 // Print the fields of a class or record, including their source locations.
176 void DetailedRecordsEmitter::printFields(Record *Rec, raw_ostream &OS) {
177  const auto &ValueList = Rec->getValues();
178  if (ValueList.empty()) {
179  OS << " Fields: (none)\n";
180  return;
181  }
182 
183  OS << " Fields:\n";
184  for (const RecordVal &Value : ValueList)
185  if (!Rec->isTemplateArg(Value.getNameInit())) {
186  OS << " ";
187  Value.print(OS, false);
188  OS << formatv(" |{0}|\n",
190  }
191 }
192 
193 namespace llvm {
194 
195 // This function is called by TableGen after parsing the files.
196 
198  // Instantiate the emitter class and invoke run().
199  DetailedRecordsEmitter(RK).run(OS);
200 }
201 
202 } // namespace llvm
MemoryBuffer.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::RecordKeeper
Definition: Record.h:1771
llvm::Record::getSuperClasses
ArrayRef< std::pair< Record *, SMRange > > getSuperClasses() const
Definition: Record.h:1571
NL
#define NL
Definition: DetailedRecordsBackend.cpp:30
DenseMap.h
llvm::Record::getLoc
ArrayRef< SMLoc > getLoc() const
Definition: Record.h:1552
Format.h
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
TableGenBackend.h
llvm::Record::getTemplateArgs
ArrayRef< Init * > getTemplateArgs() const
Definition: Record.h:1563
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::SrcMgr
SourceMgr SrcMgr
Definition: Error.cpp:24
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
FormatVariadic.h
SourceMgr.h
Error.h
llvm::EmitDetailedRecords
void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS)
Definition: DetailedRecordsBackend.cpp:197
llvm::Record::getValues
ArrayRef< RecordVal > getValues() const
Definition: Record.h:1567
I
#define I(x, y, z)
Definition: MD5.cpp:59
StringExtras.h
ArrayRef.h
llvm::Value::print
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4598
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Record
Definition: Record.h:1472
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::Init
Definition: Record.h:271
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::Record::getValue
const RecordVal * getValue(const Init *Name) const
Definition: Record.h:1585
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::Record::isTemplateArg
bool isTemplateArg(Init *Name) const
Definition: Record.h:1581
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::RecordVal
This class represents a field in a record, including its name, type, value, and source location.
Definition: Record.h:1402
Record.h
llvm::Record::hasDirectSuperClass
bool hasDirectSuperClass(const Record *SuperClass) const
Determine whether this record has the specified direct superclass.
Definition: Record.cpp:2347
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::SourceMgr::getFormattedLocationNoOffset
std::string getFormattedLocationNoOffset(SMLoc Loc, bool IncludePath=false) const
Get a string with the SMLoc filename and line number formatted in the standard style.
Definition: SourceMgr.cpp:204