xref: /openbsd-src/gnu/llvm/llvm/include/llvm/Support/ScopedPrinter.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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