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/StringExtras.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/DataTypes.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/JSON.h"
20 #include "llvm/Support/raw_ostream.h"
21
22 namespace llvm {
23
24 template <typename T> struct EnumEntry {
25 StringRef Name;
26 // While Name suffices in most of the cases, in certain cases
27 // GNU style and LLVM style of ELFDumper do not
28 // display same string for same enum. The AltName if initialized appropriately
29 // will hold the string that GNU style emits.
30 // Example:
31 // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
32 // "Advanced Micro Devices X86-64" on GNU style
33 StringRef AltName;
34 T Value;
EnumEntryEnumEntry35 constexpr EnumEntry(StringRef N, StringRef A, T V)
36 : Name(N), AltName(A), Value(V) {}
EnumEntryEnumEntry37 constexpr EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
38 };
39
40 struct HexNumber {
41 // To avoid sign-extension we have to explicitly cast to the appropriate
42 // unsigned type. The overloads are here so that every type that is implicitly
43 // convertible to an integer (including enums and endian helpers) can be used
44 // without requiring type traits or call-site changes.
HexNumberHexNumber45 HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
HexNumberHexNumber46 HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
HexNumberHexNumber47 HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
HexNumberHexNumber48 HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
HexNumberHexNumber49 HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
HexNumberHexNumber50 HexNumber(signed long long Value)
51 : Value(static_cast<unsigned long long>(Value)) {}
HexNumberHexNumber52 HexNumber(unsigned char Value) : Value(Value) {}
HexNumberHexNumber53 HexNumber(unsigned short Value) : Value(Value) {}
HexNumberHexNumber54 HexNumber(unsigned int Value) : Value(Value) {}
HexNumberHexNumber55 HexNumber(unsigned long Value) : Value(Value) {}
HexNumberHexNumber56 HexNumber(unsigned long long Value) : Value(Value) {}
57 uint64_t Value;
58 };
59
60 struct FlagEntry {
FlagEntryFlagEntry61 FlagEntry(StringRef Name, char Value)
62 : Name(Name), Value(static_cast<unsigned char>(Value)) {}
FlagEntryFlagEntry63 FlagEntry(StringRef Name, signed char Value)
64 : Name(Name), Value(static_cast<unsigned char>(Value)) {}
FlagEntryFlagEntry65 FlagEntry(StringRef Name, signed short Value)
66 : Name(Name), Value(static_cast<unsigned short>(Value)) {}
FlagEntryFlagEntry67 FlagEntry(StringRef Name, signed int Value)
68 : Name(Name), Value(static_cast<unsigned int>(Value)) {}
FlagEntryFlagEntry69 FlagEntry(StringRef Name, signed long Value)
70 : Name(Name), Value(static_cast<unsigned long>(Value)) {}
FlagEntryFlagEntry71 FlagEntry(StringRef Name, signed long long Value)
72 : Name(Name), Value(static_cast<unsigned long long>(Value)) {}
FlagEntryFlagEntry73 FlagEntry(StringRef Name, unsigned char Value) : Name(Name), Value(Value) {}
FlagEntryFlagEntry74 FlagEntry(StringRef Name, unsigned short Value) : Name(Name), Value(Value) {}
FlagEntryFlagEntry75 FlagEntry(StringRef Name, unsigned int Value) : Name(Name), Value(Value) {}
FlagEntryFlagEntry76 FlagEntry(StringRef Name, unsigned long Value) : Name(Name), Value(Value) {}
FlagEntryFlagEntry77 FlagEntry(StringRef Name, unsigned long long Value)
78 : Name(Name), Value(Value) {}
79 StringRef Name;
80 uint64_t Value;
81 };
82
83 raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
84
to_string(const T & Value)85 template <class T> std::string to_string(const T &Value) {
86 std::string number;
87 raw_string_ostream stream(number);
88 stream << Value;
89 return stream.str();
90 }
91
92 template <typename T, typename TEnum>
enumToString(T Value,ArrayRef<EnumEntry<TEnum>> EnumValues)93 std::string enumToString(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
94 for (const EnumEntry<TEnum> &EnumItem : EnumValues)
95 if (EnumItem.Value == Value)
96 return std::string(EnumItem.AltName);
97 return utohexstr(Value, true);
98 }
99
100 class ScopedPrinter {
101 public:
102 enum class ScopedPrinterKind {
103 Base,
104 JSON,
105 };
106
107 ScopedPrinter(raw_ostream &OS,
108 ScopedPrinterKind Kind = ScopedPrinterKind::Base)
OS(OS)109 : OS(OS), Kind(Kind) {}
110
getKind()111 ScopedPrinterKind getKind() const { return Kind; }
112
classof(const ScopedPrinter * SP)113 static bool classof(const ScopedPrinter *SP) {
114 return SP->getKind() == ScopedPrinterKind::Base;
115 }
116
117 virtual ~ScopedPrinter() = default;
118
flush()119 void flush() { OS.flush(); }
120
121 void indent(int Levels = 1) { IndentLevel += Levels; }
122
123 void unindent(int Levels = 1) {
124 IndentLevel = IndentLevel > Levels ? IndentLevel - Levels : 0;
125 }
126
resetIndent()127 void resetIndent() { IndentLevel = 0; }
128
getIndentLevel()129 int getIndentLevel() { return IndentLevel; }
130
setPrefix(StringRef P)131 void setPrefix(StringRef P) { Prefix = P; }
132
printIndent()133 void printIndent() {
134 OS << Prefix;
135 for (int i = 0; i < IndentLevel; ++i)
136 OS << " ";
137 }
138
hex(T Value)139 template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
140
141 template <typename T, typename TEnum>
printEnum(StringRef Label,T Value,ArrayRef<EnumEntry<TEnum>> EnumValues)142 void printEnum(StringRef Label, T Value,
143 ArrayRef<EnumEntry<TEnum>> EnumValues) {
144 StringRef Name;
145 bool Found = false;
146 for (const auto &EnumItem : EnumValues) {
147 if (EnumItem.Value == Value) {
148 Name = EnumItem.Name;
149 Found = true;
150 break;
151 }
152 }
153
154 if (Found)
155 printHex(Label, Name, Value);
156 else
157 printHex(Label, Value);
158 }
159
160 template <typename T, typename TFlag>
161 void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
162 TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
163 TFlag EnumMask3 = {}) {
164 SmallVector<FlagEntry, 10> SetFlags;
165
166 for (const auto &Flag : Flags) {
167 if (Flag.Value == 0)
168 continue;
169
170 TFlag EnumMask{};
171 if (Flag.Value & EnumMask1)
172 EnumMask = EnumMask1;
173 else if (Flag.Value & EnumMask2)
174 EnumMask = EnumMask2;
175 else if (Flag.Value & EnumMask3)
176 EnumMask = EnumMask3;
177 bool IsEnum = (Flag.Value & EnumMask) != 0;
178 if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
179 (IsEnum && (Value & EnumMask) == Flag.Value)) {
180 SetFlags.emplace_back(Flag.Name, Flag.Value);
181 }
182 }
183
184 llvm::sort(SetFlags, &flagName);
185 printFlagsImpl(Label, hex(Value), SetFlags);
186 }
187
printFlags(StringRef Label,T Value)188 template <typename T> void printFlags(StringRef Label, T Value) {
189 SmallVector<HexNumber, 10> SetFlags;
190 uint64_t Flag = 1;
191 uint64_t Curr = Value;
192 while (Curr > 0) {
193 if (Curr & 1)
194 SetFlags.emplace_back(Flag);
195 Curr >>= 1;
196 Flag <<= 1;
197 }
198 printFlagsImpl(Label, hex(Value), SetFlags);
199 }
200
printNumber(StringRef Label,uint64_t Value)201 virtual void printNumber(StringRef Label, uint64_t Value) {
202 startLine() << Label << ": " << Value << "\n";
203 }
204
printNumber(StringRef Label,uint32_t Value)205 virtual void printNumber(StringRef Label, uint32_t Value) {
206 startLine() << Label << ": " << Value << "\n";
207 }
208
printNumber(StringRef Label,uint16_t Value)209 virtual void printNumber(StringRef Label, uint16_t Value) {
210 startLine() << Label << ": " << Value << "\n";
211 }
212
printNumber(StringRef Label,uint8_t Value)213 virtual void printNumber(StringRef Label, uint8_t Value) {
214 startLine() << Label << ": " << unsigned(Value) << "\n";
215 }
216
printNumber(StringRef Label,int64_t Value)217 virtual void printNumber(StringRef Label, int64_t Value) {
218 startLine() << Label << ": " << Value << "\n";
219 }
220
printNumber(StringRef Label,int32_t Value)221 virtual void printNumber(StringRef Label, int32_t Value) {
222 startLine() << Label << ": " << Value << "\n";
223 }
224
printNumber(StringRef Label,int16_t Value)225 virtual void printNumber(StringRef Label, int16_t Value) {
226 startLine() << Label << ": " << Value << "\n";
227 }
228
printNumber(StringRef Label,int8_t Value)229 virtual void printNumber(StringRef Label, int8_t Value) {
230 startLine() << Label << ": " << int(Value) << "\n";
231 }
232
printNumber(StringRef Label,const APSInt & Value)233 virtual void printNumber(StringRef Label, const APSInt &Value) {
234 startLine() << Label << ": " << Value << "\n";
235 }
236
237 template <typename T>
printNumber(StringRef Label,StringRef Str,T Value)238 void printNumber(StringRef Label, StringRef Str, T Value) {
239 printNumberImpl(Label, Str, to_string(Value));
240 }
241
printBoolean(StringRef Label,bool Value)242 virtual void printBoolean(StringRef Label, bool Value) {
243 startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
244 }
245
printVersion(StringRef Label,T...Version)246 template <typename... T> void printVersion(StringRef Label, T... Version) {
247 startLine() << Label << ": ";
248 printVersionInternal(Version...);
249 getOStream() << "\n";
250 }
251
252 template <typename T>
printList(StringRef Label,const ArrayRef<T> List)253 void printList(StringRef Label, const ArrayRef<T> List) {
254 SmallVector<std::string, 10> StringList;
255 for (const auto &Item : List)
256 StringList.emplace_back(to_string(Item));
257 printList(Label, StringList);
258 }
259
printList(StringRef Label,const ArrayRef<bool> List)260 virtual void printList(StringRef Label, const ArrayRef<bool> List) {
261 printListImpl(Label, List);
262 }
263
printList(StringRef Label,const ArrayRef<std::string> List)264 virtual void printList(StringRef Label, const ArrayRef<std::string> List) {
265 printListImpl(Label, List);
266 }
267
printList(StringRef Label,const ArrayRef<uint64_t> List)268 virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) {
269 printListImpl(Label, List);
270 }
271
printList(StringRef Label,const ArrayRef<uint32_t> List)272 virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) {
273 printListImpl(Label, List);
274 }
275
printList(StringRef Label,const ArrayRef<uint16_t> List)276 virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) {
277 printListImpl(Label, List);
278 }
279
printList(StringRef Label,const ArrayRef<uint8_t> List)280 virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) {
281 SmallVector<unsigned> NumberList;
282 for (const uint8_t &Item : List)
283 NumberList.emplace_back(Item);
284 printListImpl(Label, NumberList);
285 }
286
printList(StringRef Label,const ArrayRef<int64_t> List)287 virtual void printList(StringRef Label, const ArrayRef<int64_t> List) {
288 printListImpl(Label, List);
289 }
290
printList(StringRef Label,const ArrayRef<int32_t> List)291 virtual void printList(StringRef Label, const ArrayRef<int32_t> List) {
292 printListImpl(Label, List);
293 }
294
printList(StringRef Label,const ArrayRef<int16_t> List)295 virtual void printList(StringRef Label, const ArrayRef<int16_t> List) {
296 printListImpl(Label, List);
297 }
298
printList(StringRef Label,const ArrayRef<int8_t> List)299 virtual void printList(StringRef Label, const ArrayRef<int8_t> List) {
300 SmallVector<int> NumberList;
301 for (const int8_t &Item : List)
302 NumberList.emplace_back(Item);
303 printListImpl(Label, NumberList);
304 }
305
printList(StringRef Label,const ArrayRef<APSInt> List)306 virtual void printList(StringRef Label, const ArrayRef<APSInt> List) {
307 printListImpl(Label, List);
308 }
309
310 template <typename T, typename U>
printList(StringRef Label,const T & List,const U & Printer)311 void printList(StringRef Label, const T &List, const U &Printer) {
312 startLine() << Label << ": [";
313 ListSeparator LS;
314 for (const auto &Item : List) {
315 OS << LS;
316 Printer(OS, Item);
317 }
318 OS << "]\n";
319 }
320
printHexList(StringRef Label,const T & List)321 template <typename T> void printHexList(StringRef Label, const T &List) {
322 SmallVector<HexNumber> HexList;
323 for (const auto &Item : List)
324 HexList.emplace_back(Item);
325 printHexListImpl(Label, HexList);
326 }
327
printHex(StringRef Label,T Value)328 template <typename T> void printHex(StringRef Label, T Value) {
329 printHexImpl(Label, hex(Value));
330 }
331
printHex(StringRef Label,StringRef Str,T Value)332 template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
333 printHexImpl(Label, Str, hex(Value));
334 }
335
336 template <typename T>
printSymbolOffset(StringRef Label,StringRef Symbol,T Value)337 void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
338 printSymbolOffsetImpl(Label, Symbol, hex(Value));
339 }
340
printString(StringRef Value)341 virtual void printString(StringRef Value) { startLine() << Value << "\n"; }
342
printString(StringRef Label,StringRef Value)343 virtual void printString(StringRef Label, StringRef Value) {
344 startLine() << Label << ": " << Value << "\n";
345 }
346
printBinary(StringRef Label,StringRef Str,ArrayRef<uint8_t> Value)347 void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
348 printBinaryImpl(Label, Str, Value, false);
349 }
350
printBinary(StringRef Label,StringRef Str,ArrayRef<char> Value)351 void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
352 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
353 Value.size());
354 printBinaryImpl(Label, Str, V, false);
355 }
356
printBinary(StringRef Label,ArrayRef<uint8_t> Value)357 void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
358 printBinaryImpl(Label, StringRef(), Value, false);
359 }
360
printBinary(StringRef Label,ArrayRef<char> Value)361 void printBinary(StringRef Label, ArrayRef<char> Value) {
362 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
363 Value.size());
364 printBinaryImpl(Label, StringRef(), V, false);
365 }
366
printBinary(StringRef Label,StringRef Value)367 void printBinary(StringRef Label, StringRef Value) {
368 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
369 Value.size());
370 printBinaryImpl(Label, StringRef(), V, false);
371 }
372
printBinaryBlock(StringRef Label,ArrayRef<uint8_t> Value,uint32_t StartOffset)373 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
374 uint32_t StartOffset) {
375 printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
376 }
377
printBinaryBlock(StringRef Label,ArrayRef<uint8_t> Value)378 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
379 printBinaryImpl(Label, StringRef(), Value, true);
380 }
381
printBinaryBlock(StringRef Label,StringRef Value)382 void printBinaryBlock(StringRef Label, StringRef Value) {
383 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()),
384 Value.size());
385 printBinaryImpl(Label, StringRef(), V, true);
386 }
387
printObject(StringRef Label,const T & Value)388 template <typename T> void printObject(StringRef Label, const T &Value) {
389 printString(Label, to_string(Value));
390 }
391
objectBegin()392 virtual void objectBegin() { scopedBegin('{'); }
393
objectBegin(StringRef Label)394 virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
395
objectEnd()396 virtual void objectEnd() { scopedEnd('}'); }
397
arrayBegin()398 virtual void arrayBegin() { scopedBegin('['); }
399
arrayBegin(StringRef Label)400 virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
401
arrayEnd()402 virtual void arrayEnd() { scopedEnd(']'); }
403
startLine()404 virtual raw_ostream &startLine() {
405 printIndent();
406 return OS;
407 }
408
getOStream()409 virtual raw_ostream &getOStream() { return OS; }
410
411 private:
printVersionInternal(T Value)412 template <typename T> void printVersionInternal(T Value) {
413 getOStream() << Value;
414 }
415
416 template <typename S, typename T, typename... TArgs>
printVersionInternal(S Value,T Value2,TArgs...Args)417 void printVersionInternal(S Value, T Value2, TArgs... Args) {
418 getOStream() << Value << ".";
419 printVersionInternal(Value2, Args...);
420 }
421
flagName(const FlagEntry & LHS,const FlagEntry & RHS)422 static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) {
423 return LHS.Name < RHS.Name;
424 }
425
426 virtual void printBinaryImpl(StringRef Label, StringRef Str,
427 ArrayRef<uint8_t> Value, bool Block,
428 uint32_t StartOffset = 0);
429
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<FlagEntry> Flags)430 virtual void printFlagsImpl(StringRef Label, HexNumber Value,
431 ArrayRef<FlagEntry> Flags) {
432 startLine() << Label << " [ (" << Value << ")\n";
433 for (const auto &Flag : Flags)
434 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
435 startLine() << "]\n";
436 }
437
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<HexNumber> Flags)438 virtual void printFlagsImpl(StringRef Label, HexNumber Value,
439 ArrayRef<HexNumber> Flags) {
440 startLine() << Label << " [ (" << Value << ")\n";
441 for (const auto &Flag : Flags)
442 startLine() << " " << Flag << '\n';
443 startLine() << "]\n";
444 }
445
printListImpl(StringRef Label,const T List)446 template <typename T> void printListImpl(StringRef Label, const T List) {
447 startLine() << Label << ": [";
448 ListSeparator LS;
449 for (const auto &Item : List)
450 OS << LS << Item;
451 OS << "]\n";
452 }
453
printHexListImpl(StringRef Label,const ArrayRef<HexNumber> List)454 virtual void printHexListImpl(StringRef Label,
455 const ArrayRef<HexNumber> List) {
456 startLine() << Label << ": [";
457 ListSeparator LS;
458 for (const auto &Item : List)
459 OS << LS << hex(Item);
460 OS << "]\n";
461 }
462
printHexImpl(StringRef Label,HexNumber Value)463 virtual void printHexImpl(StringRef Label, HexNumber Value) {
464 startLine() << Label << ": " << Value << "\n";
465 }
466
printHexImpl(StringRef Label,StringRef Str,HexNumber Value)467 virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
468 startLine() << Label << ": " << Str << " (" << Value << ")\n";
469 }
470
printSymbolOffsetImpl(StringRef Label,StringRef Symbol,HexNumber Value)471 virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
472 HexNumber Value) {
473 startLine() << Label << ": " << Symbol << '+' << Value << '\n';
474 }
475
printNumberImpl(StringRef Label,StringRef Str,StringRef Value)476 virtual void printNumberImpl(StringRef Label, StringRef Str,
477 StringRef Value) {
478 startLine() << Label << ": " << Str << " (" << Value << ")\n";
479 }
480
scopedBegin(char Symbol)481 void scopedBegin(char Symbol) {
482 startLine() << Symbol << '\n';
483 indent();
484 }
485
scopedBegin(StringRef Label,char Symbol)486 void scopedBegin(StringRef Label, char Symbol) {
487 startLine() << Label;
488 if (!Label.empty())
489 OS << ' ';
490 OS << Symbol << '\n';
491 indent();
492 }
493
scopedEnd(char Symbol)494 void scopedEnd(char Symbol) {
495 unindent();
496 startLine() << Symbol << '\n';
497 }
498
499 raw_ostream &OS;
500 int IndentLevel = 0;
501 StringRef Prefix;
502 ScopedPrinterKind Kind;
503 };
504
505 template <>
506 inline void
507 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
508 support::ulittle16_t Value) {
509 startLine() << Label << ": " << hex(Value) << "\n";
510 }
511
512 struct DelimitedScope;
513
514 class JSONScopedPrinter : public ScopedPrinter {
515 private:
516 enum class Scope {
517 Array,
518 Object,
519 };
520
521 enum class ScopeKind {
522 NoAttribute,
523 Attribute,
524 NestedAttribute,
525 };
526
527 struct ScopeContext {
528 Scope Context;
529 ScopeKind Kind;
530 ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
ContextScopeContext531 : Context(Context), Kind(Kind) {}
532 };
533
534 SmallVector<ScopeContext, 8> ScopeHistory;
535 json::OStream JOS;
536 std::unique_ptr<DelimitedScope> OuterScope;
537
538 public:
539 JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
540 std::unique_ptr<DelimitedScope> &&OuterScope =
541 std::unique_ptr<DelimitedScope>{});
542
classof(const ScopedPrinter * SP)543 static bool classof(const ScopedPrinter *SP) {
544 return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
545 }
546
printNumber(StringRef Label,uint64_t Value)547 void printNumber(StringRef Label, uint64_t Value) override {
548 JOS.attribute(Label, Value);
549 }
550
printNumber(StringRef Label,uint32_t Value)551 void printNumber(StringRef Label, uint32_t Value) override {
552 JOS.attribute(Label, Value);
553 }
554
printNumber(StringRef Label,uint16_t Value)555 void printNumber(StringRef Label, uint16_t Value) override {
556 JOS.attribute(Label, Value);
557 }
558
printNumber(StringRef Label,uint8_t Value)559 void printNumber(StringRef Label, uint8_t Value) override {
560 JOS.attribute(Label, Value);
561 }
562
printNumber(StringRef Label,int64_t Value)563 void printNumber(StringRef Label, int64_t Value) override {
564 JOS.attribute(Label, Value);
565 }
566
printNumber(StringRef Label,int32_t Value)567 void printNumber(StringRef Label, int32_t Value) override {
568 JOS.attribute(Label, Value);
569 }
570
printNumber(StringRef Label,int16_t Value)571 void printNumber(StringRef Label, int16_t Value) override {
572 JOS.attribute(Label, Value);
573 }
574
printNumber(StringRef Label,int8_t Value)575 void printNumber(StringRef Label, int8_t Value) override {
576 JOS.attribute(Label, Value);
577 }
578
printNumber(StringRef Label,const APSInt & Value)579 void printNumber(StringRef Label, const APSInt &Value) override {
580 JOS.attributeBegin(Label);
581 printAPSInt(Value);
582 JOS.attributeEnd();
583 }
584
printBoolean(StringRef Label,bool Value)585 void printBoolean(StringRef Label, bool Value) override {
586 JOS.attribute(Label, Value);
587 }
588
printList(StringRef Label,const ArrayRef<bool> List)589 void printList(StringRef Label, const ArrayRef<bool> List) override {
590 printListImpl(Label, List);
591 }
592
printList(StringRef Label,const ArrayRef<std::string> List)593 void printList(StringRef Label, const ArrayRef<std::string> List) override {
594 printListImpl(Label, List);
595 }
596
printList(StringRef Label,const ArrayRef<uint64_t> List)597 void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
598 printListImpl(Label, List);
599 }
600
printList(StringRef Label,const ArrayRef<uint32_t> List)601 void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
602 printListImpl(Label, List);
603 }
604
printList(StringRef Label,const ArrayRef<uint16_t> List)605 void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
606 printListImpl(Label, List);
607 }
608
printList(StringRef Label,const ArrayRef<uint8_t> List)609 void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
610 printListImpl(Label, List);
611 }
612
printList(StringRef Label,const ArrayRef<int64_t> List)613 void printList(StringRef Label, const ArrayRef<int64_t> List) override {
614 printListImpl(Label, List);
615 }
616
printList(StringRef Label,const ArrayRef<int32_t> List)617 void printList(StringRef Label, const ArrayRef<int32_t> List) override {
618 printListImpl(Label, List);
619 }
620
printList(StringRef Label,const ArrayRef<int16_t> List)621 void printList(StringRef Label, const ArrayRef<int16_t> List) override {
622 printListImpl(Label, List);
623 }
624
printList(StringRef Label,const ArrayRef<int8_t> List)625 void printList(StringRef Label, const ArrayRef<int8_t> List) override {
626 printListImpl(Label, List);
627 }
628
printList(StringRef Label,const ArrayRef<APSInt> List)629 void printList(StringRef Label, const ArrayRef<APSInt> List) override {
630 JOS.attributeArray(Label, [&]() {
631 for (const APSInt &Item : List) {
632 printAPSInt(Item);
633 }
634 });
635 }
636
printString(StringRef Value)637 void printString(StringRef Value) override { JOS.value(Value); }
638
printString(StringRef Label,StringRef Value)639 void printString(StringRef Label, StringRef Value) override {
640 JOS.attribute(Label, Value);
641 }
642
objectBegin()643 void objectBegin() override {
644 scopedBegin({Scope::Object, ScopeKind::NoAttribute});
645 }
646
objectBegin(StringRef Label)647 void objectBegin(StringRef Label) override {
648 scopedBegin(Label, Scope::Object);
649 }
650
objectEnd()651 void objectEnd() override { scopedEnd(); }
652
arrayBegin()653 void arrayBegin() override {
654 scopedBegin({Scope::Array, ScopeKind::NoAttribute});
655 }
656
arrayBegin(StringRef Label)657 void arrayBegin(StringRef Label) override {
658 scopedBegin(Label, Scope::Array);
659 }
660
arrayEnd()661 void arrayEnd() override { scopedEnd(); }
662
663 private:
664 // Output HexNumbers as decimals so that they're easier to parse.
hexNumberToInt(HexNumber Hex)665 uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
666
printAPSInt(const APSInt & Value)667 void printAPSInt(const APSInt &Value) {
668 JOS.rawValueBegin() << Value;
669 JOS.rawValueEnd();
670 }
671
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<FlagEntry> Flags)672 void printFlagsImpl(StringRef Label, HexNumber Value,
673 ArrayRef<FlagEntry> Flags) override {
674 JOS.attributeObject(Label, [&]() {
675 JOS.attribute("RawFlags", hexNumberToInt(Value));
676 JOS.attributeArray("Flags", [&]() {
677 for (const FlagEntry &Flag : Flags) {
678 JOS.objectBegin();
679 JOS.attribute("Name", Flag.Name);
680 JOS.attribute("Value", Flag.Value);
681 JOS.objectEnd();
682 }
683 });
684 });
685 }
686
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<HexNumber> Flags)687 void printFlagsImpl(StringRef Label, HexNumber Value,
688 ArrayRef<HexNumber> Flags) override {
689 JOS.attributeObject(Label, [&]() {
690 JOS.attribute("RawFlags", hexNumberToInt(Value));
691 JOS.attributeArray("Flags", [&]() {
692 for (const HexNumber &Flag : Flags) {
693 JOS.value(Flag.Value);
694 }
695 });
696 });
697 }
698
printListImpl(StringRef Label,const T & List)699 template <typename T> void printListImpl(StringRef Label, const T &List) {
700 JOS.attributeArray(Label, [&]() {
701 for (const auto &Item : List)
702 JOS.value(Item);
703 });
704 }
705
printHexListImpl(StringRef Label,const ArrayRef<HexNumber> List)706 void printHexListImpl(StringRef Label,
707 const ArrayRef<HexNumber> List) override {
708 JOS.attributeArray(Label, [&]() {
709 for (const HexNumber &Item : List) {
710 JOS.value(hexNumberToInt(Item));
711 }
712 });
713 }
714
printHexImpl(StringRef Label,HexNumber Value)715 void printHexImpl(StringRef Label, HexNumber Value) override {
716 JOS.attribute(Label, hexNumberToInt(Value));
717 }
718
printHexImpl(StringRef Label,StringRef Str,HexNumber Value)719 void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
720 JOS.attributeObject(Label, [&]() {
721 JOS.attribute("Value", Str);
722 JOS.attribute("RawValue", hexNumberToInt(Value));
723 });
724 }
725
printSymbolOffsetImpl(StringRef Label,StringRef Symbol,HexNumber Value)726 void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
727 HexNumber Value) override {
728 JOS.attributeObject(Label, [&]() {
729 JOS.attribute("SymName", Symbol);
730 JOS.attribute("Offset", hexNumberToInt(Value));
731 });
732 }
733
printNumberImpl(StringRef Label,StringRef Str,StringRef Value)734 void printNumberImpl(StringRef Label, StringRef Str,
735 StringRef Value) override {
736 JOS.attributeObject(Label, [&]() {
737 JOS.attribute("Value", Str);
738 JOS.attributeBegin("RawValue");
739 JOS.rawValueBegin() << Value;
740 JOS.rawValueEnd();
741 JOS.attributeEnd();
742 });
743 }
744
745 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
746 bool Block, uint32_t StartOffset = 0) override {
747 JOS.attributeObject(Label, [&]() {
748 if (!Str.empty())
749 JOS.attribute("Value", Str);
750 JOS.attribute("Offset", StartOffset);
751 JOS.attributeArray("Bytes", [&]() {
752 for (uint8_t Val : Value)
753 JOS.value(Val);
754 });
755 });
756 }
757
scopedBegin(ScopeContext ScopeCtx)758 void scopedBegin(ScopeContext ScopeCtx) {
759 if (ScopeCtx.Context == Scope::Object)
760 JOS.objectBegin();
761 else if (ScopeCtx.Context == Scope::Array)
762 JOS.arrayBegin();
763 ScopeHistory.push_back(ScopeCtx);
764 }
765
scopedBegin(StringRef Label,Scope Ctx)766 void scopedBegin(StringRef Label, Scope Ctx) {
767 ScopeKind Kind = ScopeKind::Attribute;
768 if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
769 JOS.objectBegin();
770 Kind = ScopeKind::NestedAttribute;
771 }
772 JOS.attributeBegin(Label);
773 scopedBegin({Ctx, Kind});
774 }
775
scopedEnd()776 void scopedEnd() {
777 ScopeContext ScopeCtx = ScopeHistory.back();
778 if (ScopeCtx.Context == Scope::Object)
779 JOS.objectEnd();
780 else if (ScopeCtx.Context == Scope::Array)
781 JOS.arrayEnd();
782 if (ScopeCtx.Kind == ScopeKind::Attribute ||
783 ScopeCtx.Kind == ScopeKind::NestedAttribute)
784 JOS.attributeEnd();
785 if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
786 JOS.objectEnd();
787 ScopeHistory.pop_back();
788 }
789 };
790
791 struct DelimitedScope {
DelimitedScopeDelimitedScope792 DelimitedScope(ScopedPrinter &W) : W(&W) {}
DelimitedScopeDelimitedScope793 DelimitedScope() : W(nullptr) {}
794 virtual ~DelimitedScope() = default;
795 virtual void setPrinter(ScopedPrinter &W) = 0;
796 ScopedPrinter *W;
797 };
798
799 struct DictScope : DelimitedScope {
800 explicit DictScope() = default;
DictScopeDictScope801 explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
802
DictScopeDictScope803 DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
804 W.objectBegin(N);
805 }
806
setPrinterDictScope807 void setPrinter(ScopedPrinter &W) override {
808 this->W = &W;
809 W.objectBegin();
810 }
811
~DictScopeDictScope812 ~DictScope() {
813 if (W)
814 W->objectEnd();
815 }
816 };
817
818 struct ListScope : DelimitedScope {
819 explicit ListScope() = default;
ListScopeListScope820 explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
821
ListScopeListScope822 ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
823 W.arrayBegin(N);
824 }
825
setPrinterListScope826 void setPrinter(ScopedPrinter &W) override {
827 this->W = &W;
828 W.arrayBegin();
829 }
830
~ListScopeListScope831 ~ListScope() {
832 if (W)
833 W->arrayEnd();
834 }
835 };
836
837 } // namespace llvm
838
839 #endif
840