LLVM  10.0.0svn
ScopedPrinter.h
Go to the documentation of this file.
1 //===-- ScopedPrinter.h ----------------------------------------*- 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 #ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
10 #define LLVM_SUPPORT_SCOPEDPRINTER_H
11 
12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/DataTypes.h"
17 #include "llvm/Support/Endian.h"
19 #include <algorithm>
20 
21 namespace llvm {
22 
23 template <typename T> struct EnumEntry {
25  // While Name suffices in most of the cases, in certain cases
26  // GNU style and LLVM style of ELFDumper do not
27  // display same string for same enum. The AltName if initialized appropriately
28  // will hold the string that GNU style emits.
29  // Example:
30  // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
31  // "Advanced Micro Devices X86-64" on GNU style
34  EnumEntry(StringRef N, StringRef A, T V) : Name(N), AltName(A), Value(V) {}
35  EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
36 };
37 
38 struct HexNumber {
39  // To avoid sign-extension we have to explicitly cast to the appropriate
40  // unsigned type. The overloads are here so that every type that is implicitly
41  // convertible to an integer (including enums and endian helpers) can be used
42  // without requiring type traits or call-site changes.
43  HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
44  HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
45  HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
46  HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
47  HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
48  HexNumber(signed long long Value)
49  : Value(static_cast<unsigned long long>(Value)) {}
50  HexNumber(unsigned char Value) : Value(Value) {}
51  HexNumber(unsigned short Value) : Value(Value) {}
52  HexNumber(unsigned int Value) : Value(Value) {}
53  HexNumber(unsigned long Value) : Value(Value) {}
54  HexNumber(unsigned long long Value) : Value(Value) {}
55  uint64_t Value;
56 };
57 
59 const std::string to_hexString(uint64_t Value, bool UpperCase = true);
60 
61 template <class T> const std::string to_string(const T &Value) {
62  std::string number;
63  llvm::raw_string_ostream stream(number);
64  stream << Value;
65  return stream.str();
66 }
67 
69 public:
70  ScopedPrinter(raw_ostream &OS) : OS(OS), IndentLevel(0) {}
71 
72  void flush() { OS.flush(); }
73 
74  void indent(int Levels = 1) { IndentLevel += Levels; }
75 
76  void unindent(int Levels = 1) {
77  IndentLevel = std::max(0, IndentLevel - Levels);
78  }
79 
80  void resetIndent() { IndentLevel = 0; }
81 
82  int getIndentLevel() { return IndentLevel; }
83 
84  void setPrefix(StringRef P) { Prefix = P; }
85 
86  void printIndent() {
87  OS << Prefix;
88  for (int i = 0; i < IndentLevel; ++i)
89  OS << " ";
90  }
91 
92  template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
93 
94  template <typename T, typename TEnum>
95  void printEnum(StringRef Label, T Value,
96  ArrayRef<EnumEntry<TEnum>> EnumValues) {
98  bool Found = false;
99  for (const auto &EnumItem : EnumValues) {
100  if (EnumItem.Value == Value) {
101  Name = EnumItem.Name;
102  Found = true;
103  break;
104  }
105  }
106 
107  if (Found) {
108  startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
109  } else {
110  startLine() << Label << ": " << hex(Value) << "\n";
111  }
112  }
113 
114  template <typename T, typename TFlag>
116  TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
117  TFlag EnumMask3 = {}) {
118  typedef EnumEntry<TFlag> FlagEntry;
119  typedef SmallVector<FlagEntry, 10> FlagVector;
120  FlagVector SetFlags;
121 
122  for (const auto &Flag : Flags) {
123  if (Flag.Value == 0)
124  continue;
125 
126  TFlag EnumMask{};
127  if (Flag.Value & EnumMask1)
128  EnumMask = EnumMask1;
129  else if (Flag.Value & EnumMask2)
130  EnumMask = EnumMask2;
131  else if (Flag.Value & EnumMask3)
132  EnumMask = EnumMask3;
133  bool IsEnum = (Flag.Value & EnumMask) != 0;
134  if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
135  (IsEnum && (Value & EnumMask) == Flag.Value)) {
136  SetFlags.push_back(Flag);
137  }
138  }
139 
140  llvm::sort(SetFlags, &flagName<TFlag>);
141 
142  startLine() << Label << " [ (" << hex(Value) << ")\n";
143  for (const auto &Flag : SetFlags) {
144  startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
145  }
146  startLine() << "]\n";
147  }
148 
149  template <typename T> void printFlags(StringRef Label, T Value) {
150  startLine() << Label << " [ (" << hex(Value) << ")\n";
151  uint64_t Flag = 1;
152  uint64_t Curr = Value;
153  while (Curr > 0) {
154  if (Curr & 1)
155  startLine() << " " << hex(Flag) << "\n";
156  Curr >>= 1;
157  Flag <<= 1;
158  }
159  startLine() << "]\n";
160  }
161 
162  void printNumber(StringRef Label, uint64_t Value) {
163  startLine() << Label << ": " << Value << "\n";
164  }
165 
166  void printNumber(StringRef Label, uint32_t Value) {
167  startLine() << Label << ": " << Value << "\n";
168  }
169 
170  void printNumber(StringRef Label, uint16_t Value) {
171  startLine() << Label << ": " << Value << "\n";
172  }
173 
174  void printNumber(StringRef Label, uint8_t Value) {
175  startLine() << Label << ": " << unsigned(Value) << "\n";
176  }
177 
178  void printNumber(StringRef Label, int64_t Value) {
179  startLine() << Label << ": " << Value << "\n";
180  }
181 
182  void printNumber(StringRef Label, int32_t Value) {
183  startLine() << Label << ": " << Value << "\n";
184  }
185 
186  void printNumber(StringRef Label, int16_t Value) {
187  startLine() << Label << ": " << Value << "\n";
188  }
189 
190  void printNumber(StringRef Label, int8_t Value) {
191  startLine() << Label << ": " << int(Value) << "\n";
192  }
193 
194  void printNumber(StringRef Label, const APSInt &Value) {
195  startLine() << Label << ": " << Value << "\n";
196  }
197 
198  void printBoolean(StringRef Label, bool Value) {
199  startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
200  }
201 
202  template <typename... T> void printVersion(StringRef Label, T... Version) {
203  startLine() << Label << ": ";
204  printVersionInternal(Version...);
205  getOStream() << "\n";
206  }
207 
208  template <typename T> void printList(StringRef Label, const T &List) {
209  startLine() << Label << ": [";
210  bool Comma = false;
211  for (const auto &Item : List) {
212  if (Comma)
213  OS << ", ";
214  OS << Item;
215  Comma = true;
216  }
217  OS << "]\n";
218  }
219 
220  template <typename T, typename U>
221  void printList(StringRef Label, const T &List, const U &Printer) {
222  startLine() << Label << ": [";
223  bool Comma = false;
224  for (const auto &Item : List) {
225  if (Comma)
226  OS << ", ";
227  Printer(OS, Item);
228  Comma = true;
229  }
230  OS << "]\n";
231  }
232 
233  template <typename T> void printHexList(StringRef Label, const T &List) {
234  startLine() << Label << ": [";
235  bool Comma = false;
236  for (const auto &Item : List) {
237  if (Comma)
238  OS << ", ";
239  OS << hex(Item);
240  Comma = true;
241  }
242  OS << "]\n";
243  }
244 
245  template <typename T> void printHex(StringRef Label, T Value) {
246  startLine() << Label << ": " << hex(Value) << "\n";
247  }
248 
249  template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
250  startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
251  }
252 
253  template <typename T>
255  startLine() << Label << ": " << Symbol << '+' << hex(Value) << '\n';
256  }
257 
258  void printString(StringRef Value) { startLine() << Value << "\n"; }
259 
260  void printString(StringRef Label, StringRef Value) {
261  startLine() << Label << ": " << Value << "\n";
262  }
263 
264  void printString(StringRef Label, const std::string &Value) {
265  printString(Label, StringRef(Value));
266  }
267 
268  void printString(StringRef Label, const char* Value) {
269  printString(Label, StringRef(Value));
270  }
271 
272  template <typename T>
273  void printNumber(StringRef Label, StringRef Str, T Value) {
274  startLine() << Label << ": " << Str << " (" << Value << ")\n";
275  }
276 
278  printBinaryImpl(Label, Str, Value, false);
279  }
280 
281  void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
282  auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
283  Value.size());
284  printBinaryImpl(Label, Str, V, false);
285  }
286 
288  printBinaryImpl(Label, StringRef(), Value, false);
289  }
290 
291  void printBinary(StringRef Label, ArrayRef<char> Value) {
292  auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
293  Value.size());
294  printBinaryImpl(Label, StringRef(), V, false);
295  }
296 
297  void printBinary(StringRef Label, StringRef Value) {
298  auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
299  Value.size());
300  printBinaryImpl(Label, StringRef(), V, false);
301  }
302 
304  uint32_t StartOffset) {
305  printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
306  }
307 
309  printBinaryImpl(Label, StringRef(), Value, true);
310  }
311 
312  void printBinaryBlock(StringRef Label, StringRef Value) {
313  auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
314  Value.size());
315  printBinaryImpl(Label, StringRef(), V, true);
316  }
317 
318  template <typename T> void printObject(StringRef Label, const T &Value) {
319  startLine() << Label << ": " << Value << "\n";
320  }
321 
323  printIndent();
324  return OS;
325  }
326 
327  raw_ostream &getOStream() { return OS; }
328 
329 private:
330  template <typename T> void printVersionInternal(T Value) {
331  getOStream() << Value;
332  }
333 
334  template <typename S, typename T, typename... TArgs>
335  void printVersionInternal(S Value, T Value2, TArgs... Args) {
336  getOStream() << Value << ".";
337  printVersionInternal(Value2, Args...);
338  }
339 
340  template <typename T>
341  static bool flagName(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
342  return lhs.Name < rhs.Name;
343  }
344 
345  void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
346  bool Block, uint32_t StartOffset = 0);
347 
348  raw_ostream &OS;
349  int IndentLevel;
351 };
352 
353 template <>
354 inline void
355 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
357  startLine() << Label << ": " << hex(Value) << "\n";
358 }
359 
360 template<char Open, char Close>
362  explicit DelimitedScope(ScopedPrinter &W) : W(W) {
363  W.startLine() << Open << '\n';
364  W.indent();
365  }
366 
368  W.startLine() << N;
369  if (!N.empty())
370  W.getOStream() << ' ';
371  W.getOStream() << Open << '\n';
372  W.indent();
373  }
374 
376  W.unindent();
377  W.startLine() << Close << '\n';
378  }
379 
381 };
382 
383 using DictScope = DelimitedScope<'{', '}'>;
385 
386 } // namespace llvm
387 
388 #endif
void printHexList(StringRef Label, const T &List)
StringRef AltName
Definition: ScopedPrinter.h:32
HexNumber(signed long Value)
Definition: ScopedPrinter.h:47
void printEnum(StringRef Label, T Value, ArrayRef< EnumEntry< TEnum >> EnumValues)
Definition: ScopedPrinter.h:95
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void printBinary(StringRef Label, ArrayRef< char > Value)
void printBinary(StringRef Label, StringRef Value)
void printSymbolOffset(StringRef Label, StringRef Symbol, T Value)
void printBoolean(StringRef Label, bool Value)
void push_back(const T &Elt)
Definition: SmallVector.h:211
StringRef Name
Definition: ScopedPrinter.h:24
HexNumber(signed char Value)
Definition: ScopedPrinter.h:44
void printNumber(StringRef Label, int32_t Value)
print alias Alias Set Printer
HexNumber(char Value)
Definition: ScopedPrinter.h:43
void printString(StringRef Label, StringRef Value)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:450
void indent(int Levels=1)
Definition: ScopedPrinter.h:74
DelimitedScope(ScopedPrinter &W)
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:140
HexNumber(signed short Value)
Definition: ScopedPrinter.h:45
void printString(StringRef Label, const char *Value)
raw_ostream & getOStream()
EnumEntry(StringRef N, StringRef A, T V)
Definition: ScopedPrinter.h:34
void printBinary(StringRef Label, StringRef Str, ArrayRef< uint8_t > Value)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
void printNumber(StringRef Label, uint8_t Value)
void printFlags(StringRef Label, T Value)
void printBinary(StringRef Label, StringRef Str, ArrayRef< char > Value)
void printBinaryBlock(StringRef Label, StringRef Value)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:131
HexNumber(unsigned char Value)
Definition: ScopedPrinter.h:50
#define P(N)
void printString(StringRef Label, const std::string &Value)
HexNumber(unsigned short Value)
Definition: ScopedPrinter.h:51
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
HexNumber(signed int Value)
Definition: ScopedPrinter.h:46
raw_ostream & startLine()
void printNumber(StringRef Label, const APSInt &Value)
void printList(StringRef Label, const T &List)
void printVersion(StringRef Label, T... Version)
EnumEntry(StringRef N, T V)
Definition: ScopedPrinter.h:35
HexNumber(signed long long Value)
Definition: ScopedPrinter.h:48
void printHex(StringRef Label, T Value)
HexNumber(unsigned int Value)
Definition: ScopedPrinter.h:52
ScopedPrinter & W
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:519
const T * data() const
Definition: ArrayRef.h:145
HexNumber hex(T Value)
Definition: ScopedPrinter.h:92
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1095
void printNumber(StringRef Label, uint32_t Value)
void printString(StringRef Value)
void printNumber(StringRef Label, uint64_t Value)
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:390
DelimitedScope(ScopedPrinter &W, StringRef N)
void printObject(StringRef Label, const T &Value)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
void printNumber(StringRef Label, int8_t Value)
void printBinary(StringRef Label, ArrayRef< uint8_t > Value)
void printNumber(StringRef Label, int16_t Value)
const std::string to_hexString(uint64_t Value, bool UpperCase=true)
HexNumber(unsigned long Value)
Definition: ScopedPrinter.h:53
void printHex(StringRef Label, StringRef Str, T Value)
void setPrefix(StringRef P)
Definition: ScopedPrinter.h:84
void unindent(int Levels=1)
Definition: ScopedPrinter.h:76
void printFlags(StringRef Label, T Value, ArrayRef< EnumEntry< TFlag >> Flags, TFlag EnumMask1={}, TFlag EnumMask2={}, TFlag EnumMask3={})
const NodeList & List
Definition: RDFGraph.cpp:201
ScopedPrinter(raw_ostream &OS)
Definition: ScopedPrinter.h:70
#define N
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:2047
void printNumber(StringRef Label, uint16_t Value)
const std::string to_string(const T &Value)
Definition: ScopedPrinter.h:61
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:136
void printList(StringRef Label, const T &List, const U &Printer)
void printBinaryBlock(StringRef Label, ArrayRef< uint8_t > Value, uint32_t StartOffset)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
void printNumber(StringRef Label, int64_t Value)
void printNumber(StringRef Label, StringRef Str, T Value)
HexNumber(unsigned long long Value)
Definition: ScopedPrinter.h:54
const uint64_t Version
Definition: InstrProf.h:980
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
void printBinaryBlock(StringRef Label, ArrayRef< uint8_t > Value)