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