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,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