Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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;
  35.   constexpr EnumEntry(StringRef N, StringRef A, T V)
  36.       : Name(N), AltName(A), Value(V) {}
  37.   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.
  45.   HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {}
  46.   HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {}
  47.   HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {}
  48.   HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {}
  49.   HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {}
  50.   HexNumber(signed long long Value)
  51.       : Value(static_cast<unsigned long long>(Value)) {}
  52.   HexNumber(unsigned char Value) : Value(Value) {}
  53.   HexNumber(unsigned short Value) : Value(Value) {}
  54.   HexNumber(unsigned int Value) : Value(Value) {}
  55.   HexNumber(unsigned long Value) : Value(Value) {}
  56.   HexNumber(unsigned long long Value) : Value(Value) {}
  57.   uint64_t Value;
  58. };
  59.  
  60. struct FlagEntry {
  61.   FlagEntry(StringRef Name, char Value)
  62.       : Name(Name), Value(static_cast<unsigned char>(Value)) {}
  63.   FlagEntry(StringRef Name, signed char Value)
  64.       : Name(Name), Value(static_cast<unsigned char>(Value)) {}
  65.   FlagEntry(StringRef Name, signed short Value)
  66.       : Name(Name), Value(static_cast<unsigned short>(Value)) {}
  67.   FlagEntry(StringRef Name, signed int Value)
  68.       : Name(Name), Value(static_cast<unsigned int>(Value)) {}
  69.   FlagEntry(StringRef Name, signed long Value)
  70.       : Name(Name), Value(static_cast<unsigned long>(Value)) {}
  71.   FlagEntry(StringRef Name, signed long long Value)
  72.       : Name(Name), Value(static_cast<unsigned long long>(Value)) {}
  73.   FlagEntry(StringRef Name, unsigned char Value) : Name(Name), Value(Value) {}
  74.   FlagEntry(StringRef Name, unsigned short Value) : Name(Name), Value(Value) {}
  75.   FlagEntry(StringRef Name, unsigned int Value) : Name(Name), Value(Value) {}
  76.   FlagEntry(StringRef Name, unsigned long Value) : Name(Name), Value(Value) {}
  77.   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.  
  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>
  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)
  109.       : OS(OS), Kind(Kind) {}
  110.  
  111.   ScopedPrinterKind getKind() const { return Kind; }
  112.  
  113.   static bool classof(const ScopedPrinter *SP) {
  114.     return SP->getKind() == ScopedPrinterKind::Base;
  115.   }
  116.  
  117.   virtual ~ScopedPrinter() = default;
  118.  
  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.  
  127.   void resetIndent() { IndentLevel = 0; }
  128.  
  129.   int getIndentLevel() { return IndentLevel; }
  130.  
  131.   void setPrefix(StringRef P) { Prefix = P; }
  132.  
  133.   void printIndent() {
  134.     OS << Prefix;
  135.     for (int i = 0; i < IndentLevel; ++i)
  136.       OS << "  ";
  137.   }
  138.  
  139.   template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
  140.  
  141.   template <typename T, typename TEnum>
  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.  
  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.  
  201.   virtual void printNumber(StringRef Label, uint64_t Value) {
  202.     startLine() << Label << ": " << Value << "\n";
  203.   }
  204.  
  205.   virtual void printNumber(StringRef Label, uint32_t Value) {
  206.     startLine() << Label << ": " << Value << "\n";
  207.   }
  208.  
  209.   virtual void printNumber(StringRef Label, uint16_t Value) {
  210.     startLine() << Label << ": " << Value << "\n";
  211.   }
  212.  
  213.   virtual void printNumber(StringRef Label, uint8_t Value) {
  214.     startLine() << Label << ": " << unsigned(Value) << "\n";
  215.   }
  216.  
  217.   virtual void printNumber(StringRef Label, int64_t Value) {
  218.     startLine() << Label << ": " << Value << "\n";
  219.   }
  220.  
  221.   virtual void printNumber(StringRef Label, int32_t Value) {
  222.     startLine() << Label << ": " << Value << "\n";
  223.   }
  224.  
  225.   virtual void printNumber(StringRef Label, int16_t Value) {
  226.     startLine() << Label << ": " << Value << "\n";
  227.   }
  228.  
  229.   virtual void printNumber(StringRef Label, int8_t Value) {
  230.     startLine() << Label << ": " << int(Value) << "\n";
  231.   }
  232.  
  233.   virtual void printNumber(StringRef Label, const APSInt &Value) {
  234.     startLine() << Label << ": " << Value << "\n";
  235.   }
  236.  
  237.   template <typename T>
  238.   void printNumber(StringRef Label, StringRef Str, T Value) {
  239.     printNumberImpl(Label, Str, to_string(Value));
  240.   }
  241.  
  242.   virtual void printBoolean(StringRef Label, bool Value) {
  243.     startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
  244.   }
  245.  
  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>
  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.  
  260.   virtual void printList(StringRef Label, const ArrayRef<bool> List) {
  261.     printListImpl(Label, List);
  262.   }
  263.  
  264.   virtual void printList(StringRef Label, const ArrayRef<std::string> List) {
  265.     printListImpl(Label, List);
  266.   }
  267.  
  268.   virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) {
  269.     printListImpl(Label, List);
  270.   }
  271.  
  272.   virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) {
  273.     printListImpl(Label, List);
  274.   }
  275.  
  276.   virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) {
  277.     printListImpl(Label, List);
  278.   }
  279.  
  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.  
  287.   virtual void printList(StringRef Label, const ArrayRef<int64_t> List) {
  288.     printListImpl(Label, List);
  289.   }
  290.  
  291.   virtual void printList(StringRef Label, const ArrayRef<int32_t> List) {
  292.     printListImpl(Label, List);
  293.   }
  294.  
  295.   virtual void printList(StringRef Label, const ArrayRef<int16_t> List) {
  296.     printListImpl(Label, List);
  297.   }
  298.  
  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.  
  306.   virtual void printList(StringRef Label, const ArrayRef<APSInt> List) {
  307.     printListImpl(Label, List);
  308.   }
  309.  
  310.   template <typename T, typename U>
  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.  
  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.  
  328.   template <typename T> void printHex(StringRef Label, T Value) {
  329.     printHexImpl(Label, hex(Value));
  330.   }
  331.  
  332.   template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
  333.     printHexImpl(Label, Str, hex(Value));
  334.   }
  335.  
  336.   template <typename T>
  337.   void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
  338.     printSymbolOffsetImpl(Label, Symbol, hex(Value));
  339.   }
  340.  
  341.   virtual void printString(StringRef Value) { startLine() << Value << "\n"; }
  342.  
  343.   virtual void printString(StringRef Label, StringRef Value) {
  344.     startLine() << Label << ": " << Value << "\n";
  345.   }
  346.  
  347.   void printStringEscaped(StringRef Label, StringRef Value) {
  348.     printStringEscapedImpl(Label, Value);
  349.   }
  350.  
  351.   void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
  352.     printBinaryImpl(Label, Str, Value, false);
  353.   }
  354.  
  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.  
  361.   void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
  362.     printBinaryImpl(Label, StringRef(), Value, false);
  363.   }
  364.  
  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.  
  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.  
  377.   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
  378.                         uint32_t StartOffset) {
  379.     printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
  380.   }
  381.  
  382.   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
  383.     printBinaryImpl(Label, StringRef(), Value, true);
  384.   }
  385.  
  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.  
  392.   template <typename T> void printObject(StringRef Label, const T &Value) {
  393.     printString(Label, to_string(Value));
  394.   }
  395.  
  396.   virtual void objectBegin() { scopedBegin('{'); }
  397.  
  398.   virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
  399.  
  400.   virtual void objectEnd() { scopedEnd('}'); }
  401.  
  402.   virtual void arrayBegin() { scopedBegin('['); }
  403.  
  404.   virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
  405.  
  406.   virtual void arrayEnd() { scopedEnd(']'); }
  407.  
  408.   virtual raw_ostream &startLine() {
  409.     printIndent();
  410.     return OS;
  411.   }
  412.  
  413.   virtual raw_ostream &getOStream() { return OS; }
  414.  
  415. private:
  416.   template <typename T> void printVersionInternal(T Value) {
  417.     getOStream() << Value;
  418.   }
  419.  
  420.   template <typename S, typename T, typename... TArgs>
  421.   void printVersionInternal(S Value, T Value2, TArgs... Args) {
  422.     getOStream() << Value << ".";
  423.     printVersionInternal(Value2, Args...);
  424.   }
  425.  
  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.  
  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.  
  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.  
  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.  
  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.  
  467.   virtual void printHexImpl(StringRef Label, HexNumber Value) {
  468.     startLine() << Label << ": " << Value << "\n";
  469.   }
  470.  
  471.   virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
  472.     startLine() << Label << ": " << Str << " (" << Value << ")\n";
  473.   }
  474.  
  475.   virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
  476.                                      HexNumber Value) {
  477.     startLine() << Label << ": " << Symbol << '+' << Value << '\n';
  478.   }
  479.  
  480.   virtual void printNumberImpl(StringRef Label, StringRef Str,
  481.                                StringRef Value) {
  482.     startLine() << Label << ": " << Str << " (" << Value << ")\n";
  483.   }
  484.  
  485.   virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
  486.     startLine() << Label << ": ";
  487.     OS.write_escaped(Value);
  488.     OS << '\n';
  489.   }
  490.  
  491.   void scopedBegin(char Symbol) {
  492.     startLine() << Symbol << '\n';
  493.     indent();
  494.   }
  495.  
  496.   void scopedBegin(StringRef Label, char Symbol) {
  497.     startLine() << Label;
  498.     if (!Label.empty())
  499.       OS << ' ';
  500.     OS << Symbol << '\n';
  501.     indent();
  502.   }
  503.  
  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)
  541.         : 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.  
  553.   static bool classof(const ScopedPrinter *SP) {
  554.     return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
  555.   }
  556.  
  557.   void printNumber(StringRef Label, uint64_t Value) override {
  558.     JOS.attribute(Label, Value);
  559.   }
  560.  
  561.   void printNumber(StringRef Label, uint32_t Value) override {
  562.     JOS.attribute(Label, Value);
  563.   }
  564.  
  565.   void printNumber(StringRef Label, uint16_t Value) override {
  566.     JOS.attribute(Label, Value);
  567.   }
  568.  
  569.   void printNumber(StringRef Label, uint8_t Value) override {
  570.     JOS.attribute(Label, Value);
  571.   }
  572.  
  573.   void printNumber(StringRef Label, int64_t Value) override {
  574.     JOS.attribute(Label, Value);
  575.   }
  576.  
  577.   void printNumber(StringRef Label, int32_t Value) override {
  578.     JOS.attribute(Label, Value);
  579.   }
  580.  
  581.   void printNumber(StringRef Label, int16_t Value) override {
  582.     JOS.attribute(Label, Value);
  583.   }
  584.  
  585.   void printNumber(StringRef Label, int8_t Value) override {
  586.     JOS.attribute(Label, Value);
  587.   }
  588.  
  589.   void printNumber(StringRef Label, const APSInt &Value) override {
  590.     JOS.attributeBegin(Label);
  591.     printAPSInt(Value);
  592.     JOS.attributeEnd();
  593.   }
  594.  
  595.   void printBoolean(StringRef Label, bool Value) override {
  596.     JOS.attribute(Label, Value);
  597.   }
  598.  
  599.   void printList(StringRef Label, const ArrayRef<bool> List) override {
  600.     printListImpl(Label, List);
  601.   }
  602.  
  603.   void printList(StringRef Label, const ArrayRef<std::string> List) override {
  604.     printListImpl(Label, List);
  605.   }
  606.  
  607.   void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
  608.     printListImpl(Label, List);
  609.   }
  610.  
  611.   void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
  612.     printListImpl(Label, List);
  613.   }
  614.  
  615.   void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
  616.     printListImpl(Label, List);
  617.   }
  618.  
  619.   void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
  620.     printListImpl(Label, List);
  621.   }
  622.  
  623.   void printList(StringRef Label, const ArrayRef<int64_t> List) override {
  624.     printListImpl(Label, List);
  625.   }
  626.  
  627.   void printList(StringRef Label, const ArrayRef<int32_t> List) override {
  628.     printListImpl(Label, List);
  629.   }
  630.  
  631.   void printList(StringRef Label, const ArrayRef<int16_t> List) override {
  632.     printListImpl(Label, List);
  633.   }
  634.  
  635.   void printList(StringRef Label, const ArrayRef<int8_t> List) override {
  636.     printListImpl(Label, List);
  637.   }
  638.  
  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.  
  647.   void printString(StringRef Value) override { JOS.value(Value); }
  648.  
  649.   void printString(StringRef Label, StringRef Value) override {
  650.     JOS.attribute(Label, Value);
  651.   }
  652.  
  653.   void objectBegin() override {
  654.     scopedBegin({Scope::Object, ScopeKind::NoAttribute});
  655.   }
  656.  
  657.   void objectBegin(StringRef Label) override {
  658.     scopedBegin(Label, Scope::Object);
  659.   }
  660.  
  661.   void objectEnd() override { scopedEnd(); }
  662.  
  663.   void arrayBegin() override {
  664.     scopedBegin({Scope::Array, ScopeKind::NoAttribute});
  665.   }
  666.  
  667.   void arrayBegin(StringRef Label) override {
  668.     scopedBegin(Label, Scope::Array);
  669.   }
  670.  
  671.   void arrayEnd() override { scopedEnd(); }
  672.  
  673. private:
  674.   // Output HexNumbers as decimals so that they're easier to parse.
  675.   uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
  676.  
  677.   void printAPSInt(const APSInt &Value) {
  678.     JOS.rawValueBegin() << Value;
  679.     JOS.rawValueEnd();
  680.   }
  681.  
  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.  
  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.  
  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.  
  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.  
  725.   void printHexImpl(StringRef Label, HexNumber Value) override {
  726.     JOS.attribute(Label, hexNumberToInt(Value));
  727.   }
  728.  
  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.  
  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.  
  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.  
  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.  
  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.  
  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 {
  802.   DelimitedScope(ScopedPrinter &W) : W(&W) {}
  803.   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;
  811.   explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
  812.  
  813.   DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
  814.     W.objectBegin(N);
  815.   }
  816.  
  817.   void setPrinter(ScopedPrinter &W) override {
  818.     this->W = &W;
  819.     W.objectBegin();
  820.   }
  821.  
  822.   ~DictScope() {
  823.     if (W)
  824.       W->objectEnd();
  825.   }
  826. };
  827.  
  828. struct ListScope : DelimitedScope {
  829.   explicit ListScope() = default;
  830.   explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
  831.  
  832.   ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
  833.     W.arrayBegin(N);
  834.   }
  835.  
  836.   void setPrinter(ScopedPrinter &W) override {
  837.     this->W = &W;
  838.     W.arrayBegin();
  839.   }
  840.  
  841.   ~ListScope() {
  842.     if (W)
  843.       W->arrayEnd();
  844.   }
  845. };
  846.  
  847. } // namespace llvm
  848.  
  849. #endif
  850.