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
printStringEscaped(StringRef Label,StringRef Value)347 void printStringEscaped(StringRef Label, StringRef Value) {
348 printStringEscapedImpl(Label, Value);
349 }
350
printBinary(StringRef Label,StringRef Str,ArrayRef<uint8_t> Value)351 void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
352 printBinaryImpl(Label, Str, Value, false);
353 }
354
printBinary(StringRef Label,StringRef Str,ArrayRef<char> Value)355 void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
356 auto V =
357 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
358 printBinaryImpl(Label, Str, V, false);
359 }
360
printBinary(StringRef Label,ArrayRef<uint8_t> Value)361 void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
362 printBinaryImpl(Label, StringRef(), Value, false);
363 }
364
printBinary(StringRef Label,ArrayRef<char> Value)365 void printBinary(StringRef Label, ArrayRef<char> Value) {
366 auto V =
367 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
368 printBinaryImpl(Label, StringRef(), V, false);
369 }
370
printBinary(StringRef Label,StringRef Value)371 void printBinary(StringRef Label, StringRef Value) {
372 auto V =
373 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
374 printBinaryImpl(Label, StringRef(), V, false);
375 }
376
printBinaryBlock(StringRef Label,ArrayRef<uint8_t> Value,uint32_t StartOffset)377 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
378 uint32_t StartOffset) {
379 printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
380 }
381
printBinaryBlock(StringRef Label,ArrayRef<uint8_t> Value)382 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
383 printBinaryImpl(Label, StringRef(), Value, true);
384 }
385
printBinaryBlock(StringRef Label,StringRef Value)386 void printBinaryBlock(StringRef Label, StringRef Value) {
387 auto V =
388 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
389 printBinaryImpl(Label, StringRef(), V, true);
390 }
391
printObject(StringRef Label,const T & Value)392 template <typename T> void printObject(StringRef Label, const T &Value) {
393 printString(Label, to_string(Value));
394 }
395
objectBegin()396 virtual void objectBegin() { scopedBegin('{'); }
397
objectBegin(StringRef Label)398 virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
399
objectEnd()400 virtual void objectEnd() { scopedEnd('}'); }
401
arrayBegin()402 virtual void arrayBegin() { scopedBegin('['); }
403
arrayBegin(StringRef Label)404 virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
405
arrayEnd()406 virtual void arrayEnd() { scopedEnd(']'); }
407
startLine()408 virtual raw_ostream &startLine() {
409 printIndent();
410 return OS;
411 }
412
getOStream()413 virtual raw_ostream &getOStream() { return OS; }
414
415 private:
printVersionInternal(T Value)416 template <typename T> void printVersionInternal(T Value) {
417 getOStream() << Value;
418 }
419
420 template <typename S, typename T, typename... TArgs>
printVersionInternal(S Value,T Value2,TArgs...Args)421 void printVersionInternal(S Value, T Value2, TArgs... Args) {
422 getOStream() << Value << ".";
423 printVersionInternal(Value2, Args...);
424 }
425
flagName(const FlagEntry & LHS,const FlagEntry & RHS)426 static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) {
427 return LHS.Name < RHS.Name;
428 }
429
430 virtual void printBinaryImpl(StringRef Label, StringRef Str,
431 ArrayRef<uint8_t> Value, bool Block,
432 uint32_t StartOffset = 0);
433
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<FlagEntry> Flags)434 virtual void printFlagsImpl(StringRef Label, HexNumber Value,
435 ArrayRef<FlagEntry> Flags) {
436 startLine() << Label << " [ (" << Value << ")\n";
437 for (const auto &Flag : Flags)
438 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
439 startLine() << "]\n";
440 }
441
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<HexNumber> Flags)442 virtual void printFlagsImpl(StringRef Label, HexNumber Value,
443 ArrayRef<HexNumber> Flags) {
444 startLine() << Label << " [ (" << Value << ")\n";
445 for (const auto &Flag : Flags)
446 startLine() << " " << Flag << '\n';
447 startLine() << "]\n";
448 }
449
printListImpl(StringRef Label,const T List)450 template <typename T> void printListImpl(StringRef Label, const T List) {
451 startLine() << Label << ": [";
452 ListSeparator LS;
453 for (const auto &Item : List)
454 OS << LS << Item;
455 OS << "]\n";
456 }
457
printHexListImpl(StringRef Label,const ArrayRef<HexNumber> List)458 virtual void printHexListImpl(StringRef Label,
459 const ArrayRef<HexNumber> List) {
460 startLine() << Label << ": [";
461 ListSeparator LS;
462 for (const auto &Item : List)
463 OS << LS << hex(Item);
464 OS << "]\n";
465 }
466
printHexImpl(StringRef Label,HexNumber Value)467 virtual void printHexImpl(StringRef Label, HexNumber Value) {
468 startLine() << Label << ": " << Value << "\n";
469 }
470
printHexImpl(StringRef Label,StringRef Str,HexNumber Value)471 virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
472 startLine() << Label << ": " << Str << " (" << Value << ")\n";
473 }
474
printSymbolOffsetImpl(StringRef Label,StringRef Symbol,HexNumber Value)475 virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
476 HexNumber Value) {
477 startLine() << Label << ": " << Symbol << '+' << Value << '\n';
478 }
479
printNumberImpl(StringRef Label,StringRef Str,StringRef Value)480 virtual void printNumberImpl(StringRef Label, StringRef Str,
481 StringRef Value) {
482 startLine() << Label << ": " << Str << " (" << Value << ")\n";
483 }
484
printStringEscapedImpl(StringRef Label,StringRef Value)485 virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
486 startLine() << Label << ": ";
487 OS.write_escaped(Value);
488 OS << '\n';
489 }
490
scopedBegin(char Symbol)491 void scopedBegin(char Symbol) {
492 startLine() << Symbol << '\n';
493 indent();
494 }
495
scopedBegin(StringRef Label,char Symbol)496 void scopedBegin(StringRef Label, char Symbol) {
497 startLine() << Label;
498 if (!Label.empty())
499 OS << ' ';
500 OS << Symbol << '\n';
501 indent();
502 }
503
scopedEnd(char Symbol)504 void scopedEnd(char Symbol) {
505 unindent();
506 startLine() << Symbol << '\n';
507 }
508
509 raw_ostream &OS;
510 int IndentLevel = 0;
511 StringRef Prefix;
512 ScopedPrinterKind Kind;
513 };
514
515 template <>
516 inline void
517 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
518 support::ulittle16_t Value) {
519 startLine() << Label << ": " << hex(Value) << "\n";
520 }
521
522 struct DelimitedScope;
523
524 class JSONScopedPrinter : public ScopedPrinter {
525 private:
526 enum class Scope {
527 Array,
528 Object,
529 };
530
531 enum class ScopeKind {
532 NoAttribute,
533 Attribute,
534 NestedAttribute,
535 };
536
537 struct ScopeContext {
538 Scope Context;
539 ScopeKind Kind;
540 ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
ContextScopeContext541 : Context(Context), Kind(Kind) {}
542 };
543
544 SmallVector<ScopeContext, 8> ScopeHistory;
545 json::OStream JOS;
546 std::unique_ptr<DelimitedScope> OuterScope;
547
548 public:
549 JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
550 std::unique_ptr<DelimitedScope> &&OuterScope =
551 std::unique_ptr<DelimitedScope>{});
552
classof(const ScopedPrinter * SP)553 static bool classof(const ScopedPrinter *SP) {
554 return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
555 }
556
printNumber(StringRef Label,uint64_t Value)557 void printNumber(StringRef Label, uint64_t Value) override {
558 JOS.attribute(Label, Value);
559 }
560
printNumber(StringRef Label,uint32_t Value)561 void printNumber(StringRef Label, uint32_t Value) override {
562 JOS.attribute(Label, Value);
563 }
564
printNumber(StringRef Label,uint16_t Value)565 void printNumber(StringRef Label, uint16_t Value) override {
566 JOS.attribute(Label, Value);
567 }
568
printNumber(StringRef Label,uint8_t Value)569 void printNumber(StringRef Label, uint8_t Value) override {
570 JOS.attribute(Label, Value);
571 }
572
printNumber(StringRef Label,int64_t Value)573 void printNumber(StringRef Label, int64_t Value) override {
574 JOS.attribute(Label, Value);
575 }
576
printNumber(StringRef Label,int32_t Value)577 void printNumber(StringRef Label, int32_t Value) override {
578 JOS.attribute(Label, Value);
579 }
580
printNumber(StringRef Label,int16_t Value)581 void printNumber(StringRef Label, int16_t Value) override {
582 JOS.attribute(Label, Value);
583 }
584
printNumber(StringRef Label,int8_t Value)585 void printNumber(StringRef Label, int8_t Value) override {
586 JOS.attribute(Label, Value);
587 }
588
printNumber(StringRef Label,const APSInt & Value)589 void printNumber(StringRef Label, const APSInt &Value) override {
590 JOS.attributeBegin(Label);
591 printAPSInt(Value);
592 JOS.attributeEnd();
593 }
594
printBoolean(StringRef Label,bool Value)595 void printBoolean(StringRef Label, bool Value) override {
596 JOS.attribute(Label, Value);
597 }
598
printList(StringRef Label,const ArrayRef<bool> List)599 void printList(StringRef Label, const ArrayRef<bool> List) override {
600 printListImpl(Label, List);
601 }
602
printList(StringRef Label,const ArrayRef<std::string> List)603 void printList(StringRef Label, const ArrayRef<std::string> List) override {
604 printListImpl(Label, List);
605 }
606
printList(StringRef Label,const ArrayRef<uint64_t> List)607 void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
608 printListImpl(Label, List);
609 }
610
printList(StringRef Label,const ArrayRef<uint32_t> List)611 void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
612 printListImpl(Label, List);
613 }
614
printList(StringRef Label,const ArrayRef<uint16_t> List)615 void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
616 printListImpl(Label, List);
617 }
618
printList(StringRef Label,const ArrayRef<uint8_t> List)619 void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
620 printListImpl(Label, List);
621 }
622
printList(StringRef Label,const ArrayRef<int64_t> List)623 void printList(StringRef Label, const ArrayRef<int64_t> List) override {
624 printListImpl(Label, List);
625 }
626
printList(StringRef Label,const ArrayRef<int32_t> List)627 void printList(StringRef Label, const ArrayRef<int32_t> List) override {
628 printListImpl(Label, List);
629 }
630
printList(StringRef Label,const ArrayRef<int16_t> List)631 void printList(StringRef Label, const ArrayRef<int16_t> List) override {
632 printListImpl(Label, List);
633 }
634
printList(StringRef Label,const ArrayRef<int8_t> List)635 void printList(StringRef Label, const ArrayRef<int8_t> List) override {
636 printListImpl(Label, List);
637 }
638
printList(StringRef Label,const ArrayRef<APSInt> List)639 void printList(StringRef Label, const ArrayRef<APSInt> List) override {
640 JOS.attributeArray(Label, [&]() {
641 for (const APSInt &Item : List) {
642 printAPSInt(Item);
643 }
644 });
645 }
646
printString(StringRef Value)647 void printString(StringRef Value) override { JOS.value(Value); }
648
printString(StringRef Label,StringRef Value)649 void printString(StringRef Label, StringRef Value) override {
650 JOS.attribute(Label, Value);
651 }
652
objectBegin()653 void objectBegin() override {
654 scopedBegin({Scope::Object, ScopeKind::NoAttribute});
655 }
656
objectBegin(StringRef Label)657 void objectBegin(StringRef Label) override {
658 scopedBegin(Label, Scope::Object);
659 }
660
objectEnd()661 void objectEnd() override { scopedEnd(); }
662
arrayBegin()663 void arrayBegin() override {
664 scopedBegin({Scope::Array, ScopeKind::NoAttribute});
665 }
666
arrayBegin(StringRef Label)667 void arrayBegin(StringRef Label) override {
668 scopedBegin(Label, Scope::Array);
669 }
670
arrayEnd()671 void arrayEnd() override { scopedEnd(); }
672
673 private:
674 // Output HexNumbers as decimals so that they're easier to parse.
hexNumberToInt(HexNumber Hex)675 uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
676
printAPSInt(const APSInt & Value)677 void printAPSInt(const APSInt &Value) {
678 JOS.rawValueBegin() << Value;
679 JOS.rawValueEnd();
680 }
681
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<FlagEntry> Flags)682 void printFlagsImpl(StringRef Label, HexNumber Value,
683 ArrayRef<FlagEntry> Flags) override {
684 JOS.attributeObject(Label, [&]() {
685 JOS.attribute("RawFlags", hexNumberToInt(Value));
686 JOS.attributeArray("Flags", [&]() {
687 for (const FlagEntry &Flag : Flags) {
688 JOS.objectBegin();
689 JOS.attribute("Name", Flag.Name);
690 JOS.attribute("Value", Flag.Value);
691 JOS.objectEnd();
692 }
693 });
694 });
695 }
696
printFlagsImpl(StringRef Label,HexNumber Value,ArrayRef<HexNumber> Flags)697 void printFlagsImpl(StringRef Label, HexNumber Value,
698 ArrayRef<HexNumber> Flags) override {
699 JOS.attributeObject(Label, [&]() {
700 JOS.attribute("RawFlags", hexNumberToInt(Value));
701 JOS.attributeArray("Flags", [&]() {
702 for (const HexNumber &Flag : Flags) {
703 JOS.value(Flag.Value);
704 }
705 });
706 });
707 }
708
printListImpl(StringRef Label,const T & List)709 template <typename T> void printListImpl(StringRef Label, const T &List) {
710 JOS.attributeArray(Label, [&]() {
711 for (const auto &Item : List)
712 JOS.value(Item);
713 });
714 }
715
printHexListImpl(StringRef Label,const ArrayRef<HexNumber> List)716 void printHexListImpl(StringRef Label,
717 const ArrayRef<HexNumber> List) override {
718 JOS.attributeArray(Label, [&]() {
719 for (const HexNumber &Item : List) {
720 JOS.value(hexNumberToInt(Item));
721 }
722 });
723 }
724
printHexImpl(StringRef Label,HexNumber Value)725 void printHexImpl(StringRef Label, HexNumber Value) override {
726 JOS.attribute(Label, hexNumberToInt(Value));
727 }
728
printHexImpl(StringRef Label,StringRef Str,HexNumber Value)729 void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
730 JOS.attributeObject(Label, [&]() {
731 JOS.attribute("Value", Str);
732 JOS.attribute("RawValue", hexNumberToInt(Value));
733 });
734 }
735
printSymbolOffsetImpl(StringRef Label,StringRef Symbol,HexNumber Value)736 void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
737 HexNumber Value) override {
738 JOS.attributeObject(Label, [&]() {
739 JOS.attribute("SymName", Symbol);
740 JOS.attribute("Offset", hexNumberToInt(Value));
741 });
742 }
743
printNumberImpl(StringRef Label,StringRef Str,StringRef Value)744 void printNumberImpl(StringRef Label, StringRef Str,
745 StringRef Value) override {
746 JOS.attributeObject(Label, [&]() {
747 JOS.attribute("Value", Str);
748 JOS.attributeBegin("RawValue");
749 JOS.rawValueBegin() << Value;
750 JOS.rawValueEnd();
751 JOS.attributeEnd();
752 });
753 }
754
755 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
756 bool Block, uint32_t StartOffset = 0) override {
757 JOS.attributeObject(Label, [&]() {
758 if (!Str.empty())
759 JOS.attribute("Value", Str);
760 JOS.attribute("Offset", StartOffset);
761 JOS.attributeArray("Bytes", [&]() {
762 for (uint8_t Val : Value)
763 JOS.value(Val);
764 });
765 });
766 }
767
scopedBegin(ScopeContext ScopeCtx)768 void scopedBegin(ScopeContext ScopeCtx) {
769 if (ScopeCtx.Context == Scope::Object)
770 JOS.objectBegin();
771 else if (ScopeCtx.Context == Scope::Array)
772 JOS.arrayBegin();
773 ScopeHistory.push_back(ScopeCtx);
774 }
775
scopedBegin(StringRef Label,Scope Ctx)776 void scopedBegin(StringRef Label, Scope Ctx) {
777 ScopeKind Kind = ScopeKind::Attribute;
778 if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
779 JOS.objectBegin();
780 Kind = ScopeKind::NestedAttribute;
781 }
782 JOS.attributeBegin(Label);
783 scopedBegin({Ctx, Kind});
784 }
785
scopedEnd()786 void scopedEnd() {
787 ScopeContext ScopeCtx = ScopeHistory.back();
788 if (ScopeCtx.Context == Scope::Object)
789 JOS.objectEnd();
790 else if (ScopeCtx.Context == Scope::Array)
791 JOS.arrayEnd();
792 if (ScopeCtx.Kind == ScopeKind::Attribute ||
793 ScopeCtx.Kind == ScopeKind::NestedAttribute)
794 JOS.attributeEnd();
795 if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
796 JOS.objectEnd();
797 ScopeHistory.pop_back();
798 }
799 };
800
801 struct DelimitedScope {
DelimitedScopeDelimitedScope802 DelimitedScope(ScopedPrinter &W) : W(&W) {}
DelimitedScopeDelimitedScope803 DelimitedScope() : W(nullptr) {}
804 virtual ~DelimitedScope() = default;
805 virtual void setPrinter(ScopedPrinter &W) = 0;
806 ScopedPrinter *W;
807 };
808
809 struct DictScope : DelimitedScope {
810 explicit DictScope() = default;
DictScopeDictScope811 explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
812
DictScopeDictScope813 DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
814 W.objectBegin(N);
815 }
816
setPrinterDictScope817 void setPrinter(ScopedPrinter &W) override {
818 this->W = &W;
819 W.objectBegin();
820 }
821
~DictScopeDictScope822 ~DictScope() {
823 if (W)
824 W->objectEnd();
825 }
826 };
827
828 struct ListScope : DelimitedScope {
829 explicit ListScope() = default;
ListScopeListScope830 explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
831
ListScopeListScope832 ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
833 W.arrayBegin(N);
834 }
835
setPrinterListScope836 void setPrinter(ScopedPrinter &W) override {
837 this->W = &W;
838 W.arrayBegin();
839 }
840
~ListScopeListScope841 ~ListScope() {
842 if (W)
843 W->arrayEnd();
844 }
845 };
846
847 } // namespace llvm
848
849 #endif
850