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 number;
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 = {}, ArrayRef<FlagEntry> ExtraFlags = {}) {
164 SmallVector<FlagEntry, 10> SetFlags(ExtraFlags.begin(), ExtraFlags.end());
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,char Value)201 virtual void printNumber(StringRef Label, char Value) {
202 startLine() << Label << ": " << static_cast<int>(Value) << "\n";
203 }
204
printNumber(StringRef Label,signed char Value)205 virtual void printNumber(StringRef Label, signed char Value) {
206 startLine() << Label << ": " << static_cast<int>(Value) << "\n";
207 }
208
printNumber(StringRef Label,unsigned char Value)209 virtual void printNumber(StringRef Label, unsigned char Value) {
210 startLine() << Label << ": " << static_cast<unsigned>(Value) << "\n";
211 }
212
printNumber(StringRef Label,short Value)213 virtual void printNumber(StringRef Label, short Value) {
214 startLine() << Label << ": " << Value << "\n";
215 }
216
printNumber(StringRef Label,unsigned short Value)217 virtual void printNumber(StringRef Label, unsigned short Value) {
218 startLine() << Label << ": " << Value << "\n";
219 }
220
printNumber(StringRef Label,int Value)221 virtual void printNumber(StringRef Label, int Value) {
222 startLine() << Label << ": " << Value << "\n";
223 }
224
printNumber(StringRef Label,unsigned int Value)225 virtual void printNumber(StringRef Label, unsigned int Value) {
226 startLine() << Label << ": " << Value << "\n";
227 }
228
printNumber(StringRef Label,long Value)229 virtual void printNumber(StringRef Label, long Value) {
230 startLine() << Label << ": " << Value << "\n";
231 }
232
printNumber(StringRef Label,unsigned long Value)233 virtual void printNumber(StringRef Label, unsigned long Value) {
234 startLine() << Label << ": " << Value << "\n";
235 }
236
printNumber(StringRef Label,long long Value)237 virtual void printNumber(StringRef Label, long long Value) {
238 startLine() << Label << ": " << Value << "\n";
239 }
240
printNumber(StringRef Label,unsigned long long Value)241 virtual void printNumber(StringRef Label, unsigned long long Value) {
242 startLine() << Label << ": " << Value << "\n";
243 }
244
printNumber(StringRef Label,const APSInt & Value)245 virtual void printNumber(StringRef Label, const APSInt &Value) {
246 startLine() << Label << ": " << Value << "\n";
247 }
248
printNumber(StringRef Label,float Value)249 virtual void printNumber(StringRef Label, float Value) {
250 startLine() << Label << ": " << format("%5.1f", Value) << "\n";
251 }
252
printNumber(StringRef Label,double Value)253 virtual void printNumber(StringRef Label, double Value) {
254 startLine() << Label << ": " << format("%5.1f", Value) << "\n";
255 }
256
257 template <typename T>
printNumber(StringRef Label,StringRef Str,T Value)258 void printNumber(StringRef Label, StringRef Str, T Value) {
259 printNumberImpl(Label, Str, to_string(Value));
260 }
261
printBoolean(StringRef Label,bool Value)262 virtual void printBoolean(StringRef Label, bool Value) {
263 startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
264 }
265
printVersion(StringRef Label,T...Version)266 template <typename... T> void printVersion(StringRef Label, T... Version) {
267 startLine() << Label << ": ";
268 printVersionInternal(Version...);
269 getOStream() << "\n";
270 }
271
272 template <typename T>
printList(StringRef Label,const ArrayRef<T> List)273 void printList(StringRef Label, const ArrayRef<T> List) {
274 SmallVector<std::string, 10> StringList;
275 for (const auto &Item : List)
276 StringList.emplace_back(to_string(Item));
277 printList(Label, StringList);
278 }
279
printList(StringRef Label,const ArrayRef<bool> List)280 virtual void printList(StringRef Label, const ArrayRef<bool> List) {
281 printListImpl(Label, List);
282 }
283
printList(StringRef Label,const ArrayRef<std::string> List)284 virtual void printList(StringRef Label, const ArrayRef<std::string> List) {
285 printListImpl(Label, List);
286 }
287
printList(StringRef Label,const ArrayRef<uint64_t> List)288 virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) {
289 printListImpl(Label, List);
290 }
291
printList(StringRef Label,const ArrayRef<uint32_t> List)292 virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) {
293 printListImpl(Label, List);
294 }
295
printList(StringRef Label,const ArrayRef<uint16_t> List)296 virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) {
297 printListImpl(Label, List);
298 }
299
printList(StringRef Label,const ArrayRef<uint8_t> List)300 virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) {
301 SmallVector<unsigned> NumberList;
302 for (const uint8_t &Item : List)
303 NumberList.emplace_back(Item);
304 printListImpl(Label, NumberList);
305 }
306
printList(StringRef Label,const ArrayRef<int64_t> List)307 virtual void printList(StringRef Label, const ArrayRef<int64_t> List) {
308 printListImpl(Label, List);
309 }
310
printList(StringRef Label,const ArrayRef<int32_t> List)311 virtual void printList(StringRef Label, const ArrayRef<int32_t> List) {
312 printListImpl(Label, List);
313 }
314
printList(StringRef Label,const ArrayRef<int16_t> List)315 virtual void printList(StringRef Label, const ArrayRef<int16_t> List) {
316 printListImpl(Label, List);
317 }
318
printList(StringRef Label,const ArrayRef<int8_t> List)319 virtual void printList(StringRef Label, const ArrayRef<int8_t> List) {
320 SmallVector<int> NumberList;
321 for (const int8_t &Item : List)
322 NumberList.emplace_back(Item);
323 printListImpl(Label, NumberList);
324 }
325
printList(StringRef Label,const ArrayRef<APSInt> List)326 virtual void printList(StringRef Label, const ArrayRef<APSInt> List) {
327 printListImpl(Label, List);
328 }
329
330 template <typename T, typename U>
printList(StringRef Label,const T & List,const U & Printer)331 void printList(StringRef Label, const T &List, const U &Printer) {
332 startLine() << Label << ": [";
333 ListSeparator LS;
334 for (const auto &Item : List) {
335 OS << LS;
336 Printer(OS, Item);
337 }
338 OS << "]\n";
339 }
340
printHexList(StringRef Label,const T & List)341 template <typename T> void printHexList(StringRef Label, const T &List) {
342 SmallVector<HexNumber> HexList;
343 for (const auto &Item : List)
344 HexList.emplace_back(Item);
345 printHexListImpl(Label, HexList);
346 }
347
printHex(StringRef Label,T Value)348 template <typename T> void printHex(StringRef Label, T Value) {
349 printHexImpl(Label, hex(Value));
350 }
351
printHex(StringRef Label,StringRef Str,T Value)352 template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
353 printHexImpl(Label, Str, hex(Value));
354 }
355
356 template <typename T>
printSymbolOffset(StringRef Label,StringRef Symbol,T Value)357 void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
358 printSymbolOffsetImpl(Label, Symbol, hex(Value));
359 }
360
printString(StringRef Value)361 virtual void printString(StringRef Value) { startLine() << Value << "\n"; }
362
printString(StringRef Label,StringRef Value)363 virtual void printString(StringRef Label, StringRef Value) {
364 startLine() << Label << ": " << Value << "\n";
365 }
366
printStringEscaped(StringRef Label,StringRef Value)367 void printStringEscaped(StringRef Label, StringRef Value) {
368 printStringEscapedImpl(Label, Value);
369 }
370
printBinary(StringRef Label,StringRef Str,ArrayRef<uint8_t> Value)371 void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
372 printBinaryImpl(Label, Str, Value, false);
373 }
374
printBinary(StringRef Label,StringRef Str,ArrayRef<char> Value)375 void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
376 auto V =
377 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
378 printBinaryImpl(Label, Str, V, false);
379 }
380
printBinary(StringRef Label,ArrayRef<uint8_t> Value)381 void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
382 printBinaryImpl(Label, StringRef(), Value, false);
383 }
384
printBinary(StringRef Label,ArrayRef<char> Value)385 void printBinary(StringRef Label, ArrayRef<char> Value) {
386 auto V =
387 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
388 printBinaryImpl(Label, StringRef(), V, false);
389 }
390
printBinary(StringRef Label,StringRef Value)391 void printBinary(StringRef Label, StringRef Value) {
392 auto V =
393 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
394 printBinaryImpl(Label, StringRef(), V, false);
395 }
396
printBinaryBlock(StringRef Label,ArrayRef<uint8_t> Value,uint32_t StartOffset)397 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
398 uint32_t StartOffset) {
399 printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
400 }
401
printBinaryBlock(StringRef Label,ArrayRef<uint8_t> Value)402 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
403 printBinaryImpl(Label, StringRef(), Value, true);
404 }
405
printBinaryBlock(StringRef Label,StringRef Value)406 void printBinaryBlock(StringRef Label, StringRef Value) {
407 auto V =
408 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
409 printBinaryImpl(Label, StringRef(), V, true);
410 }
411
printObject(StringRef Label,const T & Value)412 template <typename T> void printObject(StringRef Label, const T &Value) {
413 printString(Label, to_string(Value));
414 }
415
objectBegin()416 virtual void objectBegin() { scopedBegin('{'); }
417
objectBegin(StringRef Label)418 virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
419
objectEnd()420 virtual void objectEnd() { scopedEnd('}'); }
421
arrayBegin()422 virtual void arrayBegin() { scopedBegin('['); }
423
arrayBegin(StringRef Label)424 virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
425
arrayEnd()426 virtual void arrayEnd() { scopedEnd(']'); }
427
startLine()428 virtual raw_ostream &startLine() {
429 printIndent();
430 return OS;
431 }
432
getOStream()433 virtual raw_ostream &getOStream() { return OS; }
434
435 private:
printVersionInternal(T Value)436 template <typename T> void printVersionInternal(T Value) {
437 getOStream() << Value;
438 }
439
440 template <typename S, typename T, typename... TArgs>
printVersionInternal(S Value,T Value2,TArgs...Args)441 void printVersionInternal(S Value, T Value2, TArgs... Args) {
442 getOStream() << Value << ".";
443 printVersionInternal(Value2, Args...);
444 }
445
flagName(const FlagEntry & LHS,const FlagEntry & RHS)446 static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) {
447 return LHS.Name < RHS.Name;
448 }
449
450 virtual void printBinaryImpl(StringRef Label, StringRef Str,
451 ArrayRef<uint8_t> Value, bool Block,
452 uint32_t StartOffset = 0);
453
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<FlagEntry> Flags)454 virtual void printFlagsImpl(StringRef Label, HexNumber Value,
455 ArrayRef<FlagEntry> Flags) {
456 startLine() << Label << " [ (" << Value << ")\n";
457 for (const auto &Flag : Flags)
458 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
459 startLine() << "]\n";
460 }
461
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<HexNumber> Flags)462 virtual void printFlagsImpl(StringRef Label, HexNumber Value,
463 ArrayRef<HexNumber> Flags) {
464 startLine() << Label << " [ (" << Value << ")\n";
465 for (const auto &Flag : Flags)
466 startLine() << " " << Flag << '\n';
467 startLine() << "]\n";
468 }
469
printListImpl(StringRef Label,const T List)470 template <typename T> void printListImpl(StringRef Label, const T List) {
471 startLine() << Label << ": [";
472 ListSeparator LS;
473 for (const auto &Item : List)
474 OS << LS << Item;
475 OS << "]\n";
476 }
477
printHexListImpl(StringRef Label,const ArrayRef<HexNumber> List)478 virtual void printHexListImpl(StringRef Label,
479 const ArrayRef<HexNumber> List) {
480 startLine() << Label << ": [";
481 ListSeparator LS;
482 for (const auto &Item : List)
483 OS << LS << hex(Item);
484 OS << "]\n";
485 }
486
printHexImpl(StringRef Label,HexNumber Value)487 virtual void printHexImpl(StringRef Label, HexNumber Value) {
488 startLine() << Label << ": " << Value << "\n";
489 }
490
printHexImpl(StringRef Label,StringRef Str,HexNumber Value)491 virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
492 startLine() << Label << ": " << Str << " (" << Value << ")\n";
493 }
494
printSymbolOffsetImpl(StringRef Label,StringRef Symbol,HexNumber Value)495 virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
496 HexNumber Value) {
497 startLine() << Label << ": " << Symbol << '+' << Value << '\n';
498 }
499
printNumberImpl(StringRef Label,StringRef Str,StringRef Value)500 virtual void printNumberImpl(StringRef Label, StringRef Str,
501 StringRef Value) {
502 startLine() << Label << ": " << Str << " (" << Value << ")\n";
503 }
504
printStringEscapedImpl(StringRef Label,StringRef Value)505 virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
506 startLine() << Label << ": ";
507 OS.write_escaped(Value);
508 OS << '\n';
509 }
510
scopedBegin(char Symbol)511 void scopedBegin(char Symbol) {
512 startLine() << Symbol << '\n';
513 indent();
514 }
515
scopedBegin(StringRef Label,char Symbol)516 void scopedBegin(StringRef Label, char Symbol) {
517 startLine() << Label;
518 if (!Label.empty())
519 OS << ' ';
520 OS << Symbol << '\n';
521 indent();
522 }
523
scopedEnd(char Symbol)524 void scopedEnd(char Symbol) {
525 unindent();
526 startLine() << Symbol << '\n';
527 }
528
529 raw_ostream &OS;
530 int IndentLevel = 0;
531 StringRef Prefix;
532 ScopedPrinterKind Kind;
533 };
534
535 template <>
536 inline void
537 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
538 support::ulittle16_t Value) {
539 startLine() << Label << ": " << hex(Value) << "\n";
540 }
541
542 struct DelimitedScope;
543
544 class JSONScopedPrinter : public ScopedPrinter {
545 private:
546 enum class Scope {
547 Array,
548 Object,
549 };
550
551 enum class ScopeKind {
552 NoAttribute,
553 Attribute,
554 NestedAttribute,
555 };
556
557 struct ScopeContext {
558 Scope Context;
559 ScopeKind Kind;
560 ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
ContextScopeContext561 : Context(Context), Kind(Kind) {}
562 };
563
564 SmallVector<ScopeContext, 8> ScopeHistory;
565 json::OStream JOS;
566 std::unique_ptr<DelimitedScope> OuterScope;
567
568 public:
569 JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
570 std::unique_ptr<DelimitedScope> &&OuterScope =
571 std::unique_ptr<DelimitedScope>{});
572
classof(const ScopedPrinter * SP)573 static bool classof(const ScopedPrinter *SP) {
574 return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
575 }
576
printNumber(StringRef Label,char Value)577 void printNumber(StringRef Label, char Value) override {
578 JOS.attribute(Label, Value);
579 }
580
printNumber(StringRef Label,signed char Value)581 void printNumber(StringRef Label, signed char Value) override {
582 JOS.attribute(Label, Value);
583 }
584
printNumber(StringRef Label,unsigned char Value)585 void printNumber(StringRef Label, unsigned char Value) override {
586 JOS.attribute(Label, Value);
587 }
588
printNumber(StringRef Label,short Value)589 void printNumber(StringRef Label, short Value) override {
590 JOS.attribute(Label, Value);
591 }
592
printNumber(StringRef Label,unsigned short Value)593 void printNumber(StringRef Label, unsigned short Value) override {
594 JOS.attribute(Label, Value);
595 }
596
printNumber(StringRef Label,int Value)597 void printNumber(StringRef Label, int Value) override {
598 JOS.attribute(Label, Value);
599 }
600
printNumber(StringRef Label,unsigned int Value)601 void printNumber(StringRef Label, unsigned int Value) override {
602 JOS.attribute(Label, Value);
603 }
604
printNumber(StringRef Label,long Value)605 void printNumber(StringRef Label, long Value) override {
606 JOS.attribute(Label, Value);
607 }
608
printNumber(StringRef Label,unsigned long Value)609 void printNumber(StringRef Label, unsigned long Value) override {
610 JOS.attribute(Label, Value);
611 }
612
printNumber(StringRef Label,long long Value)613 void printNumber(StringRef Label, long long Value) override {
614 JOS.attribute(Label, Value);
615 }
616
printNumber(StringRef Label,unsigned long long Value)617 void printNumber(StringRef Label, unsigned long long Value) override {
618 JOS.attribute(Label, Value);
619 }
620
printNumber(StringRef Label,float Value)621 void printNumber(StringRef Label, float Value) override {
622 JOS.attribute(Label, Value);
623 }
624
printNumber(StringRef Label,double Value)625 void printNumber(StringRef Label, double Value) override {
626 JOS.attribute(Label, Value);
627 }
628
printNumber(StringRef Label,const APSInt & Value)629 void printNumber(StringRef Label, const APSInt &Value) override {
630 JOS.attributeBegin(Label);
631 printAPSInt(Value);
632 JOS.attributeEnd();
633 }
634
printBoolean(StringRef Label,bool Value)635 void printBoolean(StringRef Label, bool Value) override {
636 JOS.attribute(Label, Value);
637 }
638
printList(StringRef Label,const ArrayRef<bool> List)639 void printList(StringRef Label, const ArrayRef<bool> List) override {
640 printListImpl(Label, List);
641 }
642
printList(StringRef Label,const ArrayRef<std::string> List)643 void printList(StringRef Label, const ArrayRef<std::string> List) override {
644 printListImpl(Label, List);
645 }
646
printList(StringRef Label,const ArrayRef<uint64_t> List)647 void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
648 printListImpl(Label, List);
649 }
650
printList(StringRef Label,const ArrayRef<uint32_t> List)651 void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
652 printListImpl(Label, List);
653 }
654
printList(StringRef Label,const ArrayRef<uint16_t> List)655 void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
656 printListImpl(Label, List);
657 }
658
printList(StringRef Label,const ArrayRef<uint8_t> List)659 void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
660 printListImpl(Label, List);
661 }
662
printList(StringRef Label,const ArrayRef<int64_t> List)663 void printList(StringRef Label, const ArrayRef<int64_t> List) override {
664 printListImpl(Label, List);
665 }
666
printList(StringRef Label,const ArrayRef<int32_t> List)667 void printList(StringRef Label, const ArrayRef<int32_t> List) override {
668 printListImpl(Label, List);
669 }
670
printList(StringRef Label,const ArrayRef<int16_t> List)671 void printList(StringRef Label, const ArrayRef<int16_t> List) override {
672 printListImpl(Label, List);
673 }
674
printList(StringRef Label,const ArrayRef<int8_t> List)675 void printList(StringRef Label, const ArrayRef<int8_t> List) override {
676 printListImpl(Label, List);
677 }
678
printList(StringRef Label,const ArrayRef<APSInt> List)679 void printList(StringRef Label, const ArrayRef<APSInt> List) override {
680 JOS.attributeArray(Label, [&]() {
681 for (const APSInt &Item : List) {
682 printAPSInt(Item);
683 }
684 });
685 }
686
printString(StringRef Value)687 void printString(StringRef Value) override { JOS.value(Value); }
688
printString(StringRef Label,StringRef Value)689 void printString(StringRef Label, StringRef Value) override {
690 JOS.attribute(Label, Value);
691 }
692
objectBegin()693 void objectBegin() override {
694 scopedBegin({Scope::Object, ScopeKind::NoAttribute});
695 }
696
objectBegin(StringRef Label)697 void objectBegin(StringRef Label) override {
698 scopedBegin(Label, Scope::Object);
699 }
700
objectEnd()701 void objectEnd() override { scopedEnd(); }
702
arrayBegin()703 void arrayBegin() override {
704 scopedBegin({Scope::Array, ScopeKind::NoAttribute});
705 }
706
arrayBegin(StringRef Label)707 void arrayBegin(StringRef Label) override {
708 scopedBegin(Label, Scope::Array);
709 }
710
arrayEnd()711 void arrayEnd() override { scopedEnd(); }
712
713 private:
714 // Output HexNumbers as decimals so that they're easier to parse.
hexNumberToInt(HexNumber Hex)715 uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
716
printAPSInt(const APSInt & Value)717 void printAPSInt(const APSInt &Value) {
718 JOS.rawValueBegin() << Value;
719 JOS.rawValueEnd();
720 }
721
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<FlagEntry> Flags)722 void printFlagsImpl(StringRef Label, HexNumber Value,
723 ArrayRef<FlagEntry> Flags) override {
724 JOS.attributeObject(Label, [&]() {
725 JOS.attribute("Value", hexNumberToInt(Value));
726 JOS.attributeArray("Flags", [&]() {
727 for (const FlagEntry &Flag : Flags) {
728 JOS.objectBegin();
729 JOS.attribute("Name", Flag.Name);
730 JOS.attribute("Value", Flag.Value);
731 JOS.objectEnd();
732 }
733 });
734 });
735 }
736
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<HexNumber> Flags)737 void printFlagsImpl(StringRef Label, HexNumber Value,
738 ArrayRef<HexNumber> Flags) override {
739 JOS.attributeObject(Label, [&]() {
740 JOS.attribute("Value", hexNumberToInt(Value));
741 JOS.attributeArray("Flags", [&]() {
742 for (const HexNumber &Flag : Flags) {
743 JOS.value(Flag.Value);
744 }
745 });
746 });
747 }
748
printListImpl(StringRef Label,const T & List)749 template <typename T> void printListImpl(StringRef Label, const T &List) {
750 JOS.attributeArray(Label, [&]() {
751 for (const auto &Item : List)
752 JOS.value(Item);
753 });
754 }
755
printHexListImpl(StringRef Label,const ArrayRef<HexNumber> List)756 void printHexListImpl(StringRef Label,
757 const ArrayRef<HexNumber> List) override {
758 JOS.attributeArray(Label, [&]() {
759 for (const HexNumber &Item : List) {
760 JOS.value(hexNumberToInt(Item));
761 }
762 });
763 }
764
printHexImpl(StringRef Label,HexNumber Value)765 void printHexImpl(StringRef Label, HexNumber Value) override {
766 JOS.attribute(Label, hexNumberToInt(Value));
767 }
768
printHexImpl(StringRef Label,StringRef Str,HexNumber Value)769 void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
770 JOS.attributeObject(Label, [&]() {
771 JOS.attribute("Name", Str);
772 JOS.attribute("Value", hexNumberToInt(Value));
773 });
774 }
775
printSymbolOffsetImpl(StringRef Label,StringRef Symbol,HexNumber Value)776 void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
777 HexNumber Value) override {
778 JOS.attributeObject(Label, [&]() {
779 JOS.attribute("SymName", Symbol);
780 JOS.attribute("Offset", hexNumberToInt(Value));
781 });
782 }
783
printNumberImpl(StringRef Label,StringRef Str,StringRef Value)784 void printNumberImpl(StringRef Label, StringRef Str,
785 StringRef Value) override {
786 JOS.attributeObject(Label, [&]() {
787 JOS.attribute("Name", Str);
788 JOS.attributeBegin("Value");
789 JOS.rawValueBegin() << Value;
790 JOS.rawValueEnd();
791 JOS.attributeEnd();
792 });
793 }
794
795 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
796 bool Block, uint32_t StartOffset = 0) override {
797 JOS.attributeObject(Label, [&]() {
798 if (!Str.empty())
799 JOS.attribute("Value", Str);
800 JOS.attribute("Offset", StartOffset);
801 JOS.attributeArray("Bytes", [&]() {
802 for (uint8_t Val : Value)
803 JOS.value(Val);
804 });
805 });
806 }
807
scopedBegin(ScopeContext ScopeCtx)808 void scopedBegin(ScopeContext ScopeCtx) {
809 if (ScopeCtx.Context == Scope::Object)
810 JOS.objectBegin();
811 else if (ScopeCtx.Context == Scope::Array)
812 JOS.arrayBegin();
813 ScopeHistory.push_back(ScopeCtx);
814 }
815
scopedBegin(StringRef Label,Scope Ctx)816 void scopedBegin(StringRef Label, Scope Ctx) {
817 ScopeKind Kind = ScopeKind::Attribute;
818 if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
819 JOS.objectBegin();
820 Kind = ScopeKind::NestedAttribute;
821 }
822 JOS.attributeBegin(Label);
823 scopedBegin({Ctx, Kind});
824 }
825
scopedEnd()826 void scopedEnd() {
827 ScopeContext ScopeCtx = ScopeHistory.back();
828 if (ScopeCtx.Context == Scope::Object)
829 JOS.objectEnd();
830 else if (ScopeCtx.Context == Scope::Array)
831 JOS.arrayEnd();
832 if (ScopeCtx.Kind == ScopeKind::Attribute ||
833 ScopeCtx.Kind == ScopeKind::NestedAttribute)
834 JOS.attributeEnd();
835 if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
836 JOS.objectEnd();
837 ScopeHistory.pop_back();
838 }
839 };
840
841 struct DelimitedScope {
DelimitedScopeDelimitedScope842 DelimitedScope(ScopedPrinter &W) : W(&W) {}
DelimitedScopeDelimitedScope843 DelimitedScope() : W(nullptr) {}
844 virtual ~DelimitedScope() = default;
845 virtual void setPrinter(ScopedPrinter &W) = 0;
846 ScopedPrinter *W;
847 };
848
849 struct DictScope : DelimitedScope {
850 explicit DictScope() = default;
DictScopeDictScope851 explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
852
DictScopeDictScope853 DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
854 W.objectBegin(N);
855 }
856
setPrinterDictScope857 void setPrinter(ScopedPrinter &W) override {
858 this->W = &W;
859 W.objectBegin();
860 }
861
~DictScopeDictScope862 ~DictScope() {
863 if (W)
864 W->objectEnd();
865 }
866 };
867
868 struct ListScope : DelimitedScope {
869 explicit ListScope() = default;
ListScopeListScope870 explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
871
ListScopeListScope872 ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
873 W.arrayBegin(N);
874 }
875
setPrinterListScope876 void setPrinter(ScopedPrinter &W) override {
877 this->W = &W;
878 W.arrayBegin();
879 }
880
~ListScopeListScope881 ~ListScope() {
882 if (W)
883 W->arrayEnd();
884 }
885 };
886
887 } // namespace llvm
888
889 #endif
890