File indexing completed on 2026-05-10 08:44:34
0001
0002
0003
0004
0005
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
0027
0028
0029
0030
0031
0032
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
0042
0043
0044
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
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 }
0886
0887 #endif