LLVM  15.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/StringRef.h"
19 #include "llvm/Support/SMLoc.h"
20 #include "llvm/Support/SourceMgr.h"
22 #include "llvm/TableGen/Error.h"
23 #include "llvm/TableGen/Record.h"
24 #include <map>
25 #include <memory>
26 #include <string>
27 #include <utility>
28 
29 #define DEBUG_TYPE "detailed-records-backend"
30 
31 #define NL "\n"
32 
33 using namespace llvm;
34 
35 namespace {
36 
37 class DetailedRecordsEmitter {
38 private:
39  RecordKeeper &Records;
40 
41 public:
42  DetailedRecordsEmitter(RecordKeeper &RK) : Records(RK) {}
43 
44  void run(raw_ostream &OS);
45  void printReportHeading(raw_ostream &OS);
46  void printVariables(raw_ostream &OS);
47  void printClasses(raw_ostream &OS);
48  void printRecords(raw_ostream &OS);
49  void printSectionHeading(StringRef Title, int Count, raw_ostream &OS);
50  void printDefms(Record *Rec, raw_ostream &OS);
51  void printTemplateArgs(Record *Rec, raw_ostream &OS);
52  void printSuperclasses(Record *Rec, raw_ostream &OS);
53  void printFields(Record *Rec, raw_ostream &OS);
54 }; // emitter class
55 
56 } // anonymous namespace
57 
58 // Print the report.
60  printReportHeading(OS);
61  printVariables(OS);
62  printClasses(OS);
63  printRecords(OS);
64 }
65 
66 // Print the report heading, including the source file name.
67 void DetailedRecordsEmitter::printReportHeading(raw_ostream &OS) {
68  OS << formatv("DETAILED RECORDS for file {0}\n", Records.getInputFilename());
69 }
70 
71 // Print the global variables.
72 void DetailedRecordsEmitter::printVariables(raw_ostream &OS) {
73  const auto GlobalList = Records.getGlobals();
74  printSectionHeading("Global Variables", GlobalList.size(), OS);
75 
76  OS << NL;
77  for (const auto &Var : GlobalList) {
78  OS << Var.first << " = " << Var.second->getAsString() << NL;
79  }
80 }
81 
82 // Print the classes, including the template arguments, superclasses,
83 // and fields.
84 void DetailedRecordsEmitter::printClasses(raw_ostream &OS) {
85  const auto &ClassList = Records.getClasses();
86  printSectionHeading("Classes", ClassList.size(), OS);
87 
88  for (const auto &ClassPair : ClassList) {
89  auto *const Class = ClassPair.second.get();
90  OS << formatv("\n{0} |{1}|\n", Class->getNameInitAsString(),
91  SrcMgr.getFormattedLocationNoOffset(Class->getLoc().front()));
92  printTemplateArgs(Class, OS);
93  printSuperclasses(Class, OS);
94  printFields(Class, OS);
95  }
96 }
97 
98 // Print the records, including the defm sequences, supercasses,
99 // and fields.
100 void DetailedRecordsEmitter::printRecords(raw_ostream &OS) {
101  const auto &RecordList = Records.getDefs();
102  printSectionHeading("Records", RecordList.size(), OS);
103 
104  for (const auto &RecPair : RecordList) {
105  auto *const Rec = RecPair.second.get();
106  std::string Name = Rec->getNameInitAsString();
107  OS << formatv("\n{0} |{1}|\n", Name.empty() ? "\"\"" : Name,
108  SrcMgr.getFormattedLocationNoOffset(Rec->getLoc().front()));
109  printDefms(Rec, OS);
110  printSuperclasses(Rec, OS);
111  printFields(Rec, OS);
112  }
113 }
114 
115 // Print a section heading with the name of the section and
116 // the item count.
117 void DetailedRecordsEmitter::printSectionHeading(StringRef Title, int Count,
118  raw_ostream &OS) {
119  OS << formatv("\n{0} {1} ({2}) {0}\n", "--------------------", Title, Count);
120 }
121 
122 // Print the record's defm source locations, if any. Note that they
123 // are stored in the reverse order of their invocation.
124 void DetailedRecordsEmitter::printDefms(Record *Rec, raw_ostream &OS) {
125  const auto &LocList = Rec->getLoc();
126  if (LocList.size() < 2)
127  return;
128 
129  OS << " Defm sequence:";
130  for (unsigned I = LocList.size() - 1; I >= 1; --I) {
131  OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(LocList[I]));
132  }
133  OS << NL;
134 }
135 
136 // Print the template arguments of a class.
137 void DetailedRecordsEmitter::printTemplateArgs(Record *Rec,
138  raw_ostream &OS) {
140  if (Args.empty()) {
141  OS << " Template args: (none)\n";
142  return;
143  }
144 
145  OS << " Template args:\n";
146  for (const Init *ArgName : Args) {
147  const RecordVal *Value = Rec->getValue(ArgName);
148  assert(Value && "Template argument value not found.");
149  OS << " ";
150  Value->print(OS, false);
151  OS << formatv(" |{0}|", SrcMgr.getFormattedLocationNoOffset(Value->getLoc()));
152  OS << NL;
153  }
154 }
155 
156 // Print the superclasses of a class or record. Indirect superclasses
157 // are enclosed in parentheses.
158 void DetailedRecordsEmitter::printSuperclasses(Record *Rec, raw_ostream &OS) {
160  if (Superclasses.empty()) {
161  OS << " Superclasses: (none)\n";
162  return;
163  }
164 
165  OS << " Superclasses:";
166  for (const auto &SuperclassPair : Superclasses) {
167  auto *ClassRec = SuperclassPair.first;
168  if (Rec->hasDirectSuperClass(ClassRec))
169  OS << formatv(" {0}", ClassRec->getNameInitAsString());
170  else
171  OS << formatv(" ({0})", ClassRec->getNameInitAsString());
172  }
173  OS << NL;
174 }
175 
176 // Print the fields of a class or record, including their source locations.
177 void DetailedRecordsEmitter::printFields(Record *Rec, raw_ostream &OS) {
178  const auto &ValueList = Rec->getValues();
179  if (ValueList.empty()) {
180  OS << " Fields: (none)\n";
181  return;
182  }
183 
184  OS << " Fields:\n";
185  for (const RecordVal &Value : ValueList)
186  if (!Rec->isTemplateArg(Value.getNameInit())) {
187  OS << " ";
188  Value.print(OS, false);
189  OS << formatv(" |{0}|\n",
191  }
192 }
193 
194 namespace llvm {
195 
196 // This function is called by TableGen after parsing the files.
197 
199  // Instantiate the emitter class and invoke run().
200  DetailedRecordsEmitter(RK).run(OS);
201 }
202 
203 } // namespace llvm
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::RecordKeeper
Definition: Record.h:1807
StringRef.h
ErrorHandling.h
llvm::Record::getSuperClasses
ArrayRef< std::pair< Record *, SMRange > > getSuperClasses() const
Definition: Record.h:1607
NL
#define NL
Definition: DetailedRecordsBackend.cpp:31
llvm::Record::getLoc
ArrayRef< SMLoc > getLoc() const
Definition: Record.h:1588
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:159
llvm::Record::getTemplateArgs
ArrayRef< Init * > getTemplateArgs() const
Definition: Record.h:1599
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:251
llvm::SrcMgr
SourceMgr SrcMgr
Definition: Error.cpp:24
SMLoc.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
FormatVariadic.h
SourceMgr.h
llvm::dxil::PointerTypeAnalysis::run
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Definition: PointerTypeAnalysis.cpp:101
Error.h
llvm::EmitDetailedRecords
void EmitDetailedRecords(RecordKeeper &RK, raw_ostream &OS)
Definition: DetailedRecordsBackend.cpp:198
llvm::Record::getValues
ArrayRef< RecordVal > getValues() const
Definition: Record.h:1603
I
#define I(x, y, z)
Definition: MD5.cpp:58
ArrayRef.h
llvm::Value::print
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4579
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::Record
Definition: Record.h:1508
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:281
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::Record::getValue
const RecordVal * getValue(const Init *Name) const
Definition: Record.h:1621
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::Record::isTemplateArg
bool isTemplateArg(Init *Name) const
Definition: Record.h:1617
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
raw_ostream.h
llvm::RecordVal
This class represents a field in a record, including its name, type, value, and source location.
Definition: Record.h:1429
Record.h
llvm::Record::hasDirectSuperClass
bool hasDirectSuperClass(const Record *SuperClass) const
Determine whether this record has the specified direct superclass.
Definition: Record.cpp:2399
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
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:212