Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:34

0001 //===-- ScopedPrinter.h ----------------------------------------*- C++ -*--===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
0010 #define LLVM_SUPPORT_SCOPEDPRINTER_H
0011 
0012 #include "llvm/ADT/APSInt.h"
0013 #include "llvm/ADT/ArrayRef.h"
0014 #include "llvm/ADT/SmallVector.h"
0015 #include "llvm/ADT/StringExtras.h"
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/Support/DataTypes.h"
0018 #include "llvm/Support/Endian.h"
0019 #include "llvm/Support/JSON.h"
0020 #include "llvm/Support/raw_ostream.h"
0021 
0022 namespace llvm {
0023 
0024 template <typename T> struct EnumEntry {
0025   StringRef Name;
0026   // While Name suffices in most of the cases, in certain cases
0027   // GNU style and LLVM style of ELFDumper do not
0028   // display same string for same enum. The AltName if initialized appropriately
0029   // will hold the string that GNU style emits.
0030   // Example:
0031   // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to
0032   // "Advanced Micro Devices X86-64" on GNU style
0033   StringRef AltName;
0034   T Value;
0035   constexpr EnumEntry(StringRef N, StringRef A, T V)
0036       : Name(N), AltName(A), Value(V) {}
0037   constexpr EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {}
0038 };
0039 
0040 struct HexNumber {
0041   // To avoid sign-extension we have to explicitly cast to the appropriate
0042   // unsigned type. The overloads are here so that every type that is implicitly
0043   // convertible to an integer (including enums and endian helpers) can be used
0044   // without requiring type traits or call-site changes.
0045   HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
0046   HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
0047   HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
0048   HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
0049   HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
0050   HexNumber(signed long long Value)
0051       : Value(static_cast<unsigned long long>(Value)) {}
0052   HexNumber(unsigned char Value) : Value(Value) {}
0053   HexNumber(unsigned short Value) : Value(Value) {}
0054   HexNumber(unsigned int Value) : Value(Value) {}
0055   HexNumber(unsigned long Value) : Value(Value) {}
0056   HexNumber(unsigned long long Value) : Value(Value) {}
0057   uint64_t Value;
0058 };
0059 
0060 struct FlagEntry {
0061   FlagEntry(StringRef Name, char Value)
0062       : Name(Name), Value(static_cast<unsigned char>(Value)) {}
0063   FlagEntry(StringRef Name, signed char Value)
0064       : Name(Name), Value(static_cast<unsigned char>(Value)) {}
0065   FlagEntry(StringRef Name, signed short Value)
0066       : Name(Name), Value(static_cast<unsigned short>(Value)) {}
0067   FlagEntry(StringRef Name, signed int Value)
0068       : Name(Name), Value(static_cast<unsigned int>(Value)) {}
0069   FlagEntry(StringRef Name, signed long Value)
0070       : Name(Name), Value(static_cast<unsigned long>(Value)) {}
0071   FlagEntry(StringRef Name, signed long long Value)
0072       : Name(Name), Value(static_cast<unsigned long long>(Value)) {}
0073   FlagEntry(StringRef Name, unsigned char Value) : Name(Name), Value(Value) {}
0074   FlagEntry(StringRef Name, unsigned short Value) : Name(Name), Value(Value) {}
0075   FlagEntry(StringRef Name, unsigned int Value) : Name(Name), Value(Value) {}
0076   FlagEntry(StringRef Name, unsigned long Value) : Name(Name), Value(Value) {}
0077   FlagEntry(StringRef Name, unsigned long long Value)
0078       : Name(Name), Value(Value) {}
0079   StringRef Name;
0080   uint64_t Value;
0081 };
0082 
0083 raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
0084 
0085 template <class T> std::string to_string(const T &Value) {
0086   std::string number;
0087   raw_string_ostream stream(number);
0088   stream << Value;
0089   return number;
0090 }
0091 
0092 template <typename T, typename TEnum>
0093 std::string enumToString(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
0094   for (const EnumEntry<TEnum> &EnumItem : EnumValues)
0095     if (EnumItem.Value == Value)
0096       return std::string(EnumItem.AltName);
0097   return utohexstr(Value, true);
0098 }
0099 
0100 class ScopedPrinter {
0101 public:
0102   enum class ScopedPrinterKind {
0103     Base,
0104     JSON,
0105   };
0106 
0107   ScopedPrinter(raw_ostream &OS,
0108                 ScopedPrinterKind Kind = ScopedPrinterKind::Base)
0109       : OS(OS), Kind(Kind) {}
0110 
0111   ScopedPrinterKind getKind() const { return Kind; }
0112 
0113   static bool classof(const ScopedPrinter *SP) {
0114     return SP->getKind() == ScopedPrinterKind::Base;
0115   }
0116 
0117   virtual ~ScopedPrinter() = default;
0118 
0119   void flush() { OS.flush(); }
0120 
0121   void indent(int Levels = 1) { IndentLevel += Levels; }
0122 
0123   void unindent(int Levels = 1) {
0124     IndentLevel = IndentLevel > Levels ? IndentLevel - Levels : 0;
0125   }
0126 
0127   void resetIndent() { IndentLevel = 0; }
0128 
0129   int getIndentLevel() { return IndentLevel; }
0130 
0131   void setPrefix(StringRef P) { Prefix = P; }
0132 
0133   void printIndent() {
0134     OS << Prefix;
0135     for (int i = 0; i < IndentLevel; ++i)
0136       OS << "  ";
0137   }
0138 
0139   template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
0140 
0141   template <typename T, typename TEnum>
0142   void printEnum(StringRef Label, T Value,
0143                  ArrayRef<EnumEntry<TEnum>> EnumValues) {
0144     StringRef Name;
0145     bool Found = false;
0146     for (const auto &EnumItem : EnumValues) {
0147       if (EnumItem.Value == Value) {
0148         Name = EnumItem.Name;
0149         Found = true;
0150         break;
0151       }
0152     }
0153 
0154     if (Found)
0155       printHex(Label, Name, Value);
0156     else
0157       printHex(Label, Value);
0158   }
0159 
0160   template <typename T, typename TFlag>
0161   void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
0162                   TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
0163                   TFlag EnumMask3 = {}, ArrayRef<FlagEntry> ExtraFlags = {}) {
0164     SmallVector<FlagEntry, 10> SetFlags(ExtraFlags);
0165 
0166     for (const auto &Flag : Flags) {
0167       if (Flag.Value == 0)
0168         continue;
0169 
0170       TFlag EnumMask{};
0171       if (Flag.Value & EnumMask1)
0172         EnumMask = EnumMask1;
0173       else if (Flag.Value & EnumMask2)
0174         EnumMask = EnumMask2;
0175       else if (Flag.Value & EnumMask3)
0176         EnumMask = EnumMask3;
0177       bool IsEnum = (Flag.Value & EnumMask) != 0;
0178       if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
0179           (IsEnum && (Value & EnumMask) == Flag.Value)) {
0180         SetFlags.emplace_back(Flag.Name, Flag.Value);
0181       }
0182     }
0183 
0184     llvm::sort(SetFlags, &flagName);
0185     printFlagsImpl(Label, hex(Value), SetFlags);
0186   }
0187 
0188   template <typename T> void printFlags(StringRef Label, T Value) {
0189     SmallVector<HexNumber, 10> SetFlags;
0190     uint64_t Flag = 1;
0191     uint64_t Curr = Value;
0192     while (Curr > 0) {
0193       if (Curr & 1)
0194         SetFlags.emplace_back(Flag);
0195       Curr >>= 1;
0196       Flag <<= 1;
0197     }
0198     printFlagsImpl(Label, hex(Value), SetFlags);
0199   }
0200 
0201   virtual void printNumber(StringRef Label, char Value) {
0202     startLine() << Label << ": " << static_cast<int>(Value) << "\n";
0203   }
0204 
0205   virtual void printNumber(StringRef Label, signed char Value) {
0206     startLine() << Label << ": " << static_cast<int>(Value) << "\n";
0207   }
0208 
0209   virtual void printNumber(StringRef Label, unsigned char Value) {
0210     startLine() << Label << ": " << static_cast<unsigned>(Value) << "\n";
0211   }
0212 
0213   virtual void printNumber(StringRef Label, short Value) {
0214     startLine() << Label << ": " << Value << "\n";
0215   }
0216 
0217   virtual void printNumber(StringRef Label, unsigned short Value) {
0218     startLine() << Label << ": " << Value << "\n";
0219   }
0220 
0221   virtual void printNumber(StringRef Label, int Value) {
0222     startLine() << Label << ": " << Value << "\n";
0223   }
0224 
0225   virtual void printNumber(StringRef Label, unsigned int Value) {
0226     startLine() << Label << ": " << Value << "\n";
0227   }
0228 
0229   virtual void printNumber(StringRef Label, long Value) {
0230     startLine() << Label << ": " << Value << "\n";
0231   }
0232 
0233   virtual void printNumber(StringRef Label, unsigned long Value) {
0234     startLine() << Label << ": " << Value << "\n";
0235   }
0236 
0237   virtual void printNumber(StringRef Label, long long Value) {
0238     startLine() << Label << ": " << Value << "\n";
0239   }
0240 
0241   virtual void printNumber(StringRef Label, unsigned long long Value) {
0242     startLine() << Label << ": " << Value << "\n";
0243   }
0244 
0245   virtual void printNumber(StringRef Label, const APSInt &Value) {
0246     startLine() << Label << ": " << Value << "\n";
0247   }
0248 
0249   virtual void printNumber(StringRef Label, float Value) {
0250     startLine() << Label << ": " << format("%5.1f", Value) << "\n";
0251   }
0252 
0253   virtual void printNumber(StringRef Label, double Value) {
0254     startLine() << Label << ": " << format("%5.1f", Value) << "\n";
0255   }
0256 
0257   template <typename T>
0258   void printNumber(StringRef Label, StringRef Str, T Value) {
0259     printNumberImpl(Label, Str, to_string(Value));
0260   }
0261 
0262   virtual void printBoolean(StringRef Label, bool Value) {
0263     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
0264   }
0265 
0266   template <typename... T> void printVersion(StringRef Label, T... Version) {
0267     startLine() << Label << ": ";
0268     printVersionInternal(Version...);
0269     getOStream() << "\n";
0270   }
0271 
0272   template <typename T>
0273   void printList(StringRef Label, const ArrayRef<T> List) {
0274     SmallVector<std::string, 10> StringList;
0275     for (const auto &Item : List)
0276       StringList.emplace_back(to_string(Item));
0277     printList(Label, StringList);
0278   }
0279 
0280   virtual void printList(StringRef Label, const ArrayRef<bool> List) {
0281     printListImpl(Label, List);
0282   }
0283 
0284   virtual void printList(StringRef Label, const ArrayRef<std::string> List) {
0285     printListImpl(Label, List);
0286   }
0287 
0288   virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) {
0289     printListImpl(Label, List);
0290   }
0291 
0292   virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) {
0293     printListImpl(Label, List);
0294   }
0295 
0296   virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) {
0297     printListImpl(Label, List);
0298   }
0299 
0300   virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) {
0301     SmallVector<unsigned> NumberList;
0302     for (const uint8_t &Item : List)
0303       NumberList.emplace_back(Item);
0304     printListImpl(Label, NumberList);
0305   }
0306 
0307   virtual void printList(StringRef Label, const ArrayRef<int64_t> List) {
0308     printListImpl(Label, List);
0309   }
0310 
0311   virtual void printList(StringRef Label, const ArrayRef<int32_t> List) {
0312     printListImpl(Label, List);
0313   }
0314 
0315   virtual void printList(StringRef Label, const ArrayRef<int16_t> List) {
0316     printListImpl(Label, List);
0317   }
0318 
0319   virtual void printList(StringRef Label, const ArrayRef<int8_t> List) {
0320     SmallVector<int> NumberList;
0321     for (const int8_t &Item : List)
0322       NumberList.emplace_back(Item);
0323     printListImpl(Label, NumberList);
0324   }
0325 
0326   virtual void printList(StringRef Label, const ArrayRef<APSInt> List) {
0327     printListImpl(Label, List);
0328   }
0329 
0330   template <typename T, typename U>
0331   void printList(StringRef Label, const T &List, const U &Printer) {
0332     startLine() << Label << ": [";
0333     ListSeparator LS;
0334     for (const auto &Item : List) {
0335       OS << LS;
0336       Printer(OS, Item);
0337     }
0338     OS << "]\n";
0339   }
0340 
0341   template <typename T> void printHexList(StringRef Label, const T &List) {
0342     SmallVector<HexNumber> HexList;
0343     for (const auto &Item : List)
0344       HexList.emplace_back(Item);
0345     printHexListImpl(Label, HexList);
0346   }
0347 
0348   template <typename T> void printHex(StringRef Label, T Value) {
0349     printHexImpl(Label, hex(Value));
0350   }
0351 
0352   template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
0353     printHexImpl(Label, Str, hex(Value));
0354   }
0355 
0356   template <typename T>
0357   void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
0358     printSymbolOffsetImpl(Label, Symbol, hex(Value));
0359   }
0360 
0361   virtual void printString(StringRef Value) { startLine() << Value << "\n"; }
0362 
0363   virtual void printString(StringRef Label, StringRef Value) {
0364     startLine() << Label << ": " << Value << "\n";
0365   }
0366 
0367   void printStringEscaped(StringRef Label, StringRef Value) {
0368     printStringEscapedImpl(Label, Value);
0369   }
0370 
0371   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
0372     printBinaryImpl(Label, Str, Value, false);
0373   }
0374 
0375   void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
0376     auto V =
0377         ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
0378     printBinaryImpl(Label, Str, V, false);
0379   }
0380 
0381   void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
0382     printBinaryImpl(Label, StringRef(), Value, false);
0383   }
0384 
0385   void printBinary(StringRef Label, ArrayRef<char> Value) {
0386     auto V =
0387         ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
0388     printBinaryImpl(Label, StringRef(), V, false);
0389   }
0390 
0391   void printBinary(StringRef Label, StringRef Value) {
0392     auto V =
0393         ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
0394     printBinaryImpl(Label, StringRef(), V, false);
0395   }
0396 
0397   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
0398                         uint32_t StartOffset) {
0399     printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
0400   }
0401 
0402   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
0403     printBinaryImpl(Label, StringRef(), Value, true);
0404   }
0405 
0406   void printBinaryBlock(StringRef Label, StringRef Value) {
0407     auto V =
0408         ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
0409     printBinaryImpl(Label, StringRef(), V, true);
0410   }
0411 
0412   template <typename T> void printObject(StringRef Label, const T &Value) {
0413     printString(Label, to_string(Value));
0414   }
0415 
0416   virtual void objectBegin() { scopedBegin('{'); }
0417 
0418   virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
0419 
0420   virtual void objectEnd() { scopedEnd('}'); }
0421 
0422   virtual void arrayBegin() { scopedBegin('['); }
0423 
0424   virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
0425 
0426   virtual void arrayEnd() { scopedEnd(']'); }
0427 
0428   virtual raw_ostream &startLine() {
0429     printIndent();
0430     return OS;
0431   }
0432 
0433   virtual raw_ostream &getOStream() { return OS; }
0434 
0435 private:
0436   template <typename T> void printVersionInternal(T Value) {
0437     getOStream() << Value;
0438   }
0439 
0440   template <typename S, typename T, typename... TArgs>
0441   void printVersionInternal(S Value, T Value2, TArgs... Args) {
0442     getOStream() << Value << ".";
0443     printVersionInternal(Value2, Args...);
0444   }
0445 
0446   static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) {
0447     return LHS.Name < RHS.Name;
0448   }
0449 
0450   virtual void printBinaryImpl(StringRef Label, StringRef Str,
0451                                ArrayRef<uint8_t> Value, bool Block,
0452                                uint32_t StartOffset = 0);
0453 
0454   virtual void printFlagsImpl(StringRef Label, HexNumber Value,
0455                               ArrayRef<FlagEntry> Flags) {
0456     startLine() << Label << " [ (" << Value << ")\n";
0457     for (const auto &Flag : Flags)
0458       startLine() << "  " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
0459     startLine() << "]\n";
0460   }
0461 
0462   virtual void printFlagsImpl(StringRef Label, HexNumber Value,
0463                               ArrayRef<HexNumber> Flags) {
0464     startLine() << Label << " [ (" << Value << ")\n";
0465     for (const auto &Flag : Flags)
0466       startLine() << "  " << Flag << '\n';
0467     startLine() << "]\n";
0468   }
0469 
0470   template <typename T> void printListImpl(StringRef Label, const T List) {
0471     startLine() << Label << ": [";
0472     ListSeparator LS;
0473     for (const auto &Item : List)
0474       OS << LS << Item;
0475     OS << "]\n";
0476   }
0477 
0478   virtual void printHexListImpl(StringRef Label,
0479                                 const ArrayRef<HexNumber> List) {
0480     startLine() << Label << ": [";
0481     ListSeparator LS;
0482     for (const auto &Item : List)
0483       OS << LS << hex(Item);
0484     OS << "]\n";
0485   }
0486 
0487   virtual void printHexImpl(StringRef Label, HexNumber Value) {
0488     startLine() << Label << ": " << Value << "\n";
0489   }
0490 
0491   virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
0492     startLine() << Label << ": " << Str << " (" << Value << ")\n";
0493   }
0494 
0495   virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
0496                                      HexNumber Value) {
0497     startLine() << Label << ": " << Symbol << '+' << Value << '\n';
0498   }
0499 
0500   virtual void printNumberImpl(StringRef Label, StringRef Str,
0501                                StringRef Value) {
0502     startLine() << Label << ": " << Str << " (" << Value << ")\n";
0503   }
0504 
0505   virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
0506     startLine() << Label << ": ";
0507     OS.write_escaped(Value);
0508     OS << '\n';
0509   }
0510 
0511   void scopedBegin(char Symbol) {
0512     startLine() << Symbol << '\n';
0513     indent();
0514   }
0515 
0516   void scopedBegin(StringRef Label, char Symbol) {
0517     startLine() << Label;
0518     if (!Label.empty())
0519       OS << ' ';
0520     OS << Symbol << '\n';
0521     indent();
0522   }
0523 
0524   void scopedEnd(char Symbol) {
0525     unindent();
0526     startLine() << Symbol << '\n';
0527   }
0528 
0529   raw_ostream &OS;
0530   int IndentLevel = 0;
0531   StringRef Prefix;
0532   ScopedPrinterKind Kind;
0533 };
0534 
0535 template <>
0536 inline void
0537 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
0538                                               support::ulittle16_t Value) {
0539   startLine() << Label << ": " << hex(Value) << "\n";
0540 }
0541 
0542 struct DelimitedScope {
0543   DelimitedScope(ScopedPrinter &W) : W(&W) {}
0544   DelimitedScope() : W(nullptr) {}
0545   virtual ~DelimitedScope() = default;
0546   virtual void setPrinter(ScopedPrinter &W) = 0;
0547   ScopedPrinter *W;
0548 };
0549 
0550 class JSONScopedPrinter : public ScopedPrinter {
0551 private:
0552   enum class Scope {
0553     Array,
0554     Object,
0555   };
0556 
0557   enum class ScopeKind {
0558     NoAttribute,
0559     Attribute,
0560     NestedAttribute,
0561   };
0562 
0563   struct ScopeContext {
0564     Scope Context;
0565     ScopeKind Kind;
0566     ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
0567         : Context(Context), Kind(Kind) {}
0568   };
0569 
0570   SmallVector<ScopeContext, 8> ScopeHistory;
0571   json::OStream JOS;
0572   std::unique_ptr<DelimitedScope> OuterScope;
0573 
0574 public:
0575   JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
0576                     std::unique_ptr<DelimitedScope> &&OuterScope =
0577                         std::unique_ptr<DelimitedScope>{});
0578 
0579   static bool classof(const ScopedPrinter *SP) {
0580     return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
0581   }
0582 
0583   void printNumber(StringRef Label, char Value) override {
0584     JOS.attribute(Label, Value);
0585   }
0586 
0587   void printNumber(StringRef Label, signed char Value) override {
0588     JOS.attribute(Label, Value);
0589   }
0590 
0591   void printNumber(StringRef Label, unsigned char Value) override {
0592     JOS.attribute(Label, Value);
0593   }
0594 
0595   void printNumber(StringRef Label, short Value) override {
0596     JOS.attribute(Label, Value);
0597   }
0598 
0599   void printNumber(StringRef Label, unsigned short Value) override {
0600     JOS.attribute(Label, Value);
0601   }
0602 
0603   void printNumber(StringRef Label, int Value) override {
0604     JOS.attribute(Label, Value);
0605   }
0606 
0607   void printNumber(StringRef Label, unsigned int Value) override {
0608     JOS.attribute(Label, Value);
0609   }
0610 
0611   void printNumber(StringRef Label, long Value) override {
0612     JOS.attribute(Label, Value);
0613   }
0614 
0615   void printNumber(StringRef Label, unsigned long Value) override {
0616     JOS.attribute(Label, Value);
0617   }
0618 
0619   void printNumber(StringRef Label, long long Value) override {
0620     JOS.attribute(Label, Value);
0621   }
0622 
0623   void printNumber(StringRef Label, unsigned long long Value) override {
0624     JOS.attribute(Label, Value);
0625   }
0626 
0627   void printNumber(StringRef Label, float Value) override {
0628     JOS.attribute(Label, Value);
0629   }
0630 
0631   void printNumber(StringRef Label, double Value) override {
0632     JOS.attribute(Label, Value);
0633   }
0634 
0635   void printNumber(StringRef Label, const APSInt &Value) override {
0636     JOS.attributeBegin(Label);
0637     printAPSInt(Value);
0638     JOS.attributeEnd();
0639   }
0640 
0641   void printBoolean(StringRef Label, bool Value) override {
0642     JOS.attribute(Label, Value);
0643   }
0644 
0645   void printList(StringRef Label, const ArrayRef<bool> List) override {
0646     printListImpl(Label, List);
0647   }
0648 
0649   void printList(StringRef Label, const ArrayRef<std::string> List) override {
0650     printListImpl(Label, List);
0651   }
0652 
0653   void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
0654     printListImpl(Label, List);
0655   }
0656 
0657   void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
0658     printListImpl(Label, List);
0659   }
0660 
0661   void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
0662     printListImpl(Label, List);
0663   }
0664 
0665   void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
0666     printListImpl(Label, List);
0667   }
0668 
0669   void printList(StringRef Label, const ArrayRef<int64_t> List) override {
0670     printListImpl(Label, List);
0671   }
0672 
0673   void printList(StringRef Label, const ArrayRef<int32_t> List) override {
0674     printListImpl(Label, List);
0675   }
0676 
0677   void printList(StringRef Label, const ArrayRef<int16_t> List) override {
0678     printListImpl(Label, List);
0679   }
0680 
0681   void printList(StringRef Label, const ArrayRef<int8_t> List) override {
0682     printListImpl(Label, List);
0683   }
0684 
0685   void printList(StringRef Label, const ArrayRef<APSInt> List) override {
0686     JOS.attributeArray(Label, [&]() {
0687       for (const APSInt &Item : List) {
0688         printAPSInt(Item);
0689       }
0690     });
0691   }
0692 
0693   void printString(StringRef Value) override { JOS.value(Value); }
0694 
0695   void printString(StringRef Label, StringRef Value) override {
0696     JOS.attribute(Label, Value);
0697   }
0698 
0699   void objectBegin() override {
0700     scopedBegin({Scope::Object, ScopeKind::NoAttribute});
0701   }
0702 
0703   void objectBegin(StringRef Label) override {
0704     scopedBegin(Label, Scope::Object);
0705   }
0706 
0707   void objectEnd() override { scopedEnd(); }
0708 
0709   void arrayBegin() override {
0710     scopedBegin({Scope::Array, ScopeKind::NoAttribute});
0711   }
0712 
0713   void arrayBegin(StringRef Label) override {
0714     scopedBegin(Label, Scope::Array);
0715   }
0716 
0717   void arrayEnd() override { scopedEnd(); }
0718 
0719 private:
0720   // Output HexNumbers as decimals so that they're easier to parse.
0721   uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
0722 
0723   void printAPSInt(const APSInt &Value) {
0724     JOS.rawValueBegin() << Value;
0725     JOS.rawValueEnd();
0726   }
0727 
0728   void printFlagsImpl(StringRef Label, HexNumber Value,
0729                       ArrayRef<FlagEntry> Flags) override {
0730     JOS.attributeObject(Label, [&]() {
0731       JOS.attribute("Value", hexNumberToInt(Value));
0732       JOS.attributeArray("Flags", [&]() {
0733         for (const FlagEntry &Flag : Flags) {
0734           JOS.objectBegin();
0735           JOS.attribute("Name", Flag.Name);
0736           JOS.attribute("Value", Flag.Value);
0737           JOS.objectEnd();
0738         }
0739       });
0740     });
0741   }
0742 
0743   void printFlagsImpl(StringRef Label, HexNumber Value,
0744                       ArrayRef<HexNumber> Flags) override {
0745     JOS.attributeObject(Label, [&]() {
0746       JOS.attribute("Value", hexNumberToInt(Value));
0747       JOS.attributeArray("Flags", [&]() {
0748         for (const HexNumber &Flag : Flags) {
0749           JOS.value(Flag.Value);
0750         }
0751       });
0752     });
0753   }
0754 
0755   template <typename T> void printListImpl(StringRef Label, const T &List) {
0756     JOS.attributeArray(Label, [&]() {
0757       for (const auto &Item : List)
0758         JOS.value(Item);
0759     });
0760   }
0761 
0762   void printHexListImpl(StringRef Label,
0763                         const ArrayRef<HexNumber> List) override {
0764     JOS.attributeArray(Label, [&]() {
0765       for (const HexNumber &Item : List) {
0766         JOS.value(hexNumberToInt(Item));
0767       }
0768     });
0769   }
0770 
0771   void printHexImpl(StringRef Label, HexNumber Value) override {
0772     JOS.attribute(Label, hexNumberToInt(Value));
0773   }
0774 
0775   void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
0776     JOS.attributeObject(Label, [&]() {
0777       JOS.attribute("Name", Str);
0778       JOS.attribute("Value", hexNumberToInt(Value));
0779     });
0780   }
0781 
0782   void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
0783                              HexNumber Value) override {
0784     JOS.attributeObject(Label, [&]() {
0785       JOS.attribute("SymName", Symbol);
0786       JOS.attribute("Offset", hexNumberToInt(Value));
0787     });
0788   }
0789 
0790   void printNumberImpl(StringRef Label, StringRef Str,
0791                        StringRef Value) override {
0792     JOS.attributeObject(Label, [&]() {
0793       JOS.attribute("Name", Str);
0794       JOS.attributeBegin("Value");
0795       JOS.rawValueBegin() << Value;
0796       JOS.rawValueEnd();
0797       JOS.attributeEnd();
0798     });
0799   }
0800 
0801   void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
0802                        bool Block, uint32_t StartOffset = 0) override {
0803     JOS.attributeObject(Label, [&]() {
0804       if (!Str.empty())
0805         JOS.attribute("Value", Str);
0806       JOS.attribute("Offset", StartOffset);
0807       JOS.attributeArray("Bytes", [&]() {
0808         for (uint8_t Val : Value)
0809           JOS.value(Val);
0810       });
0811     });
0812   }
0813 
0814   void scopedBegin(ScopeContext ScopeCtx) {
0815     if (ScopeCtx.Context == Scope::Object)
0816       JOS.objectBegin();
0817     else if (ScopeCtx.Context == Scope::Array)
0818       JOS.arrayBegin();
0819     ScopeHistory.push_back(ScopeCtx);
0820   }
0821 
0822   void scopedBegin(StringRef Label, Scope Ctx) {
0823     ScopeKind Kind = ScopeKind::Attribute;
0824     if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
0825       JOS.objectBegin();
0826       Kind = ScopeKind::NestedAttribute;
0827     }
0828     JOS.attributeBegin(Label);
0829     scopedBegin({Ctx, Kind});
0830   }
0831 
0832   void scopedEnd() {
0833     ScopeContext ScopeCtx = ScopeHistory.back();
0834     if (ScopeCtx.Context == Scope::Object)
0835       JOS.objectEnd();
0836     else if (ScopeCtx.Context == Scope::Array)
0837       JOS.arrayEnd();
0838     if (ScopeCtx.Kind == ScopeKind::Attribute ||
0839         ScopeCtx.Kind == ScopeKind::NestedAttribute)
0840       JOS.attributeEnd();
0841     if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
0842       JOS.objectEnd();
0843     ScopeHistory.pop_back();
0844   }
0845 };
0846 
0847 struct DictScope : DelimitedScope {
0848   explicit DictScope() = default;
0849   explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
0850 
0851   DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
0852     W.objectBegin(N);
0853   }
0854 
0855   void setPrinter(ScopedPrinter &W) override {
0856     this->W = &W;
0857     W.objectBegin();
0858   }
0859 
0860   ~DictScope() {
0861     if (W)
0862       W->objectEnd();
0863   }
0864 };
0865 
0866 struct ListScope : DelimitedScope {
0867   explicit ListScope() = default;
0868   explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
0869 
0870   ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
0871     W.arrayBegin(N);
0872   }
0873 
0874   void setPrinter(ScopedPrinter &W) override {
0875     this->W = &W;
0876     W.arrayBegin();
0877   }
0878 
0879   ~ListScope() {
0880     if (W)
0881       W->arrayEnd();
0882   }
0883 };
0884 
0885 } // namespace llvm
0886 
0887 #endif