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 printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) { 348 printBinaryImpl(Label, Str, Value, false); 349 } 350 351 void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) { 352 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 353 Value.size()); 354 printBinaryImpl(Label, Str, V, false); 355 } 356 357 void printBinary(StringRef Label, ArrayRef<uint8_t> Value) { 358 printBinaryImpl(Label, StringRef(), Value, false); 359 } 360 361 void printBinary(StringRef Label, ArrayRef<char> Value) { 362 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 363 Value.size()); 364 printBinaryImpl(Label, StringRef(), V, false); 365 } 366 367 void printBinary(StringRef Label, StringRef Value) { 368 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 369 Value.size()); 370 printBinaryImpl(Label, StringRef(), V, false); 371 } 372 373 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value, 374 uint32_t StartOffset) { 375 printBinaryImpl(Label, StringRef(), Value, true, StartOffset); 376 } 377 378 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) { 379 printBinaryImpl(Label, StringRef(), Value, true); 380 } 381 382 void printBinaryBlock(StringRef Label, StringRef Value) { 383 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 384 Value.size()); 385 printBinaryImpl(Label, StringRef(), V, true); 386 } 387 388 template <typename T> void printObject(StringRef Label, const T &Value) { 389 printString(Label, to_string(Value)); 390 } 391 392 virtual void objectBegin() { scopedBegin('{'); } 393 394 virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); } 395 396 virtual void objectEnd() { scopedEnd('}'); } 397 398 virtual void arrayBegin() { scopedBegin('['); } 399 400 virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); } 401 402 virtual void arrayEnd() { scopedEnd(']'); } 403 404 virtual raw_ostream &startLine() { 405 printIndent(); 406 return OS; 407 } 408 409 virtual raw_ostream &getOStream() { return OS; } 410 411 private: 412 template <typename T> void printVersionInternal(T Value) { 413 getOStream() << Value; 414 } 415 416 template <typename S, typename T, typename... TArgs> 417 void printVersionInternal(S Value, T Value2, TArgs... Args) { 418 getOStream() << Value << "."; 419 printVersionInternal(Value2, Args...); 420 } 421 422 static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) { 423 return LHS.Name < RHS.Name; 424 } 425 426 virtual void printBinaryImpl(StringRef Label, StringRef Str, 427 ArrayRef<uint8_t> Value, bool Block, 428 uint32_t StartOffset = 0); 429 430 virtual void printFlagsImpl(StringRef Label, HexNumber Value, 431 ArrayRef<FlagEntry> Flags) { 432 startLine() << Label << " [ (" << Value << ")\n"; 433 for (const auto &Flag : Flags) 434 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n"; 435 startLine() << "]\n"; 436 } 437 438 virtual void printFlagsImpl(StringRef Label, HexNumber Value, 439 ArrayRef<HexNumber> Flags) { 440 startLine() << Label << " [ (" << Value << ")\n"; 441 for (const auto &Flag : Flags) 442 startLine() << " " << Flag << '\n'; 443 startLine() << "]\n"; 444 } 445 446 template <typename T> void printListImpl(StringRef Label, const T List) { 447 startLine() << Label << ": ["; 448 ListSeparator LS; 449 for (const auto &Item : List) 450 OS << LS << Item; 451 OS << "]\n"; 452 } 453 454 virtual void printHexListImpl(StringRef Label, 455 const ArrayRef<HexNumber> List) { 456 startLine() << Label << ": ["; 457 ListSeparator LS; 458 for (const auto &Item : List) 459 OS << LS << hex(Item); 460 OS << "]\n"; 461 } 462 463 virtual void printHexImpl(StringRef Label, HexNumber Value) { 464 startLine() << Label << ": " << Value << "\n"; 465 } 466 467 virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) { 468 startLine() << Label << ": " << Str << " (" << Value << ")\n"; 469 } 470 471 virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol, 472 HexNumber Value) { 473 startLine() << Label << ": " << Symbol << '+' << Value << '\n'; 474 } 475 476 virtual void printNumberImpl(StringRef Label, StringRef Str, 477 StringRef Value) { 478 startLine() << Label << ": " << Str << " (" << Value << ")\n"; 479 } 480 481 void scopedBegin(char Symbol) { 482 startLine() << Symbol << '\n'; 483 indent(); 484 } 485 486 void scopedBegin(StringRef Label, char Symbol) { 487 startLine() << Label; 488 if (!Label.empty()) 489 OS << ' '; 490 OS << Symbol << '\n'; 491 indent(); 492 } 493 494 void scopedEnd(char Symbol) { 495 unindent(); 496 startLine() << Symbol << '\n'; 497 } 498 499 raw_ostream &OS; 500 int IndentLevel = 0; 501 StringRef Prefix; 502 ScopedPrinterKind Kind; 503 }; 504 505 template <> 506 inline void 507 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label, 508 support::ulittle16_t Value) { 509 startLine() << Label << ": " << hex(Value) << "\n"; 510 } 511 512 struct DelimitedScope; 513 514 class JSONScopedPrinter : public ScopedPrinter { 515 private: 516 enum class Scope { 517 Array, 518 Object, 519 }; 520 521 enum class ScopeKind { 522 NoAttribute, 523 Attribute, 524 NestedAttribute, 525 }; 526 527 struct ScopeContext { 528 Scope Context; 529 ScopeKind Kind; 530 ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute) 531 : Context(Context), Kind(Kind) {} 532 }; 533 534 SmallVector<ScopeContext, 8> ScopeHistory; 535 json::OStream JOS; 536 std::unique_ptr<DelimitedScope> OuterScope; 537 538 public: 539 JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false, 540 std::unique_ptr<DelimitedScope> &&OuterScope = 541 std::unique_ptr<DelimitedScope>{}); 542 543 static bool classof(const ScopedPrinter *SP) { 544 return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON; 545 } 546 547 void printNumber(StringRef Label, uint64_t Value) override { 548 JOS.attribute(Label, Value); 549 } 550 551 void printNumber(StringRef Label, uint32_t Value) override { 552 JOS.attribute(Label, Value); 553 } 554 555 void printNumber(StringRef Label, uint16_t Value) override { 556 JOS.attribute(Label, Value); 557 } 558 559 void printNumber(StringRef Label, uint8_t Value) override { 560 JOS.attribute(Label, Value); 561 } 562 563 void printNumber(StringRef Label, int64_t Value) override { 564 JOS.attribute(Label, Value); 565 } 566 567 void printNumber(StringRef Label, int32_t Value) override { 568 JOS.attribute(Label, Value); 569 } 570 571 void printNumber(StringRef Label, int16_t Value) override { 572 JOS.attribute(Label, Value); 573 } 574 575 void printNumber(StringRef Label, int8_t Value) override { 576 JOS.attribute(Label, Value); 577 } 578 579 void printNumber(StringRef Label, const APSInt &Value) override { 580 JOS.attributeBegin(Label); 581 printAPSInt(Value); 582 JOS.attributeEnd(); 583 } 584 585 void printBoolean(StringRef Label, bool Value) override { 586 JOS.attribute(Label, Value); 587 } 588 589 void printList(StringRef Label, const ArrayRef<bool> List) override { 590 printListImpl(Label, List); 591 } 592 593 void printList(StringRef Label, const ArrayRef<std::string> List) override { 594 printListImpl(Label, List); 595 } 596 597 void printList(StringRef Label, const ArrayRef<uint64_t> List) override { 598 printListImpl(Label, List); 599 } 600 601 void printList(StringRef Label, const ArrayRef<uint32_t> List) override { 602 printListImpl(Label, List); 603 } 604 605 void printList(StringRef Label, const ArrayRef<uint16_t> List) override { 606 printListImpl(Label, List); 607 } 608 609 void printList(StringRef Label, const ArrayRef<uint8_t> List) override { 610 printListImpl(Label, List); 611 } 612 613 void printList(StringRef Label, const ArrayRef<int64_t> List) override { 614 printListImpl(Label, List); 615 } 616 617 void printList(StringRef Label, const ArrayRef<int32_t> List) override { 618 printListImpl(Label, List); 619 } 620 621 void printList(StringRef Label, const ArrayRef<int16_t> List) override { 622 printListImpl(Label, List); 623 } 624 625 void printList(StringRef Label, const ArrayRef<int8_t> List) override { 626 printListImpl(Label, List); 627 } 628 629 void printList(StringRef Label, const ArrayRef<APSInt> List) override { 630 JOS.attributeArray(Label, [&]() { 631 for (const APSInt &Item : List) { 632 printAPSInt(Item); 633 } 634 }); 635 } 636 637 void printString(StringRef Value) override { JOS.value(Value); } 638 639 void printString(StringRef Label, StringRef Value) override { 640 JOS.attribute(Label, Value); 641 } 642 643 void objectBegin() override { 644 scopedBegin({Scope::Object, ScopeKind::NoAttribute}); 645 } 646 647 void objectBegin(StringRef Label) override { 648 scopedBegin(Label, Scope::Object); 649 } 650 651 void objectEnd() override { scopedEnd(); } 652 653 void arrayBegin() override { 654 scopedBegin({Scope::Array, ScopeKind::NoAttribute}); 655 } 656 657 void arrayBegin(StringRef Label) override { 658 scopedBegin(Label, Scope::Array); 659 } 660 661 void arrayEnd() override { scopedEnd(); } 662 663 private: 664 // Output HexNumbers as decimals so that they're easier to parse. 665 uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; } 666 667 void printAPSInt(const APSInt &Value) { 668 JOS.rawValueBegin() << Value; 669 JOS.rawValueEnd(); 670 } 671 672 void printFlagsImpl(StringRef Label, HexNumber Value, 673 ArrayRef<FlagEntry> Flags) override { 674 JOS.attributeObject(Label, [&]() { 675 JOS.attribute("RawFlags", hexNumberToInt(Value)); 676 JOS.attributeArray("Flags", [&]() { 677 for (const FlagEntry &Flag : Flags) { 678 JOS.objectBegin(); 679 JOS.attribute("Name", Flag.Name); 680 JOS.attribute("Value", Flag.Value); 681 JOS.objectEnd(); 682 } 683 }); 684 }); 685 } 686 687 void printFlagsImpl(StringRef Label, HexNumber Value, 688 ArrayRef<HexNumber> Flags) override { 689 JOS.attributeObject(Label, [&]() { 690 JOS.attribute("RawFlags", hexNumberToInt(Value)); 691 JOS.attributeArray("Flags", [&]() { 692 for (const HexNumber &Flag : Flags) { 693 JOS.value(Flag.Value); 694 } 695 }); 696 }); 697 } 698 699 template <typename T> void printListImpl(StringRef Label, const T &List) { 700 JOS.attributeArray(Label, [&]() { 701 for (const auto &Item : List) 702 JOS.value(Item); 703 }); 704 } 705 706 void printHexListImpl(StringRef Label, 707 const ArrayRef<HexNumber> List) override { 708 JOS.attributeArray(Label, [&]() { 709 for (const HexNumber &Item : List) { 710 JOS.value(hexNumberToInt(Item)); 711 } 712 }); 713 } 714 715 void printHexImpl(StringRef Label, HexNumber Value) override { 716 JOS.attribute(Label, hexNumberToInt(Value)); 717 } 718 719 void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override { 720 JOS.attributeObject(Label, [&]() { 721 JOS.attribute("Value", Str); 722 JOS.attribute("RawValue", hexNumberToInt(Value)); 723 }); 724 } 725 726 void printSymbolOffsetImpl(StringRef Label, StringRef Symbol, 727 HexNumber Value) override { 728 JOS.attributeObject(Label, [&]() { 729 JOS.attribute("SymName", Symbol); 730 JOS.attribute("Offset", hexNumberToInt(Value)); 731 }); 732 } 733 734 void printNumberImpl(StringRef Label, StringRef Str, 735 StringRef Value) override { 736 JOS.attributeObject(Label, [&]() { 737 JOS.attribute("Value", Str); 738 JOS.attributeBegin("RawValue"); 739 JOS.rawValueBegin() << Value; 740 JOS.rawValueEnd(); 741 JOS.attributeEnd(); 742 }); 743 } 744 745 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value, 746 bool Block, uint32_t StartOffset = 0) override { 747 JOS.attributeObject(Label, [&]() { 748 if (!Str.empty()) 749 JOS.attribute("Value", Str); 750 JOS.attribute("Offset", StartOffset); 751 JOS.attributeArray("Bytes", [&]() { 752 for (uint8_t Val : Value) 753 JOS.value(Val); 754 }); 755 }); 756 } 757 758 void scopedBegin(ScopeContext ScopeCtx) { 759 if (ScopeCtx.Context == Scope::Object) 760 JOS.objectBegin(); 761 else if (ScopeCtx.Context == Scope::Array) 762 JOS.arrayBegin(); 763 ScopeHistory.push_back(ScopeCtx); 764 } 765 766 void scopedBegin(StringRef Label, Scope Ctx) { 767 ScopeKind Kind = ScopeKind::Attribute; 768 if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) { 769 JOS.objectBegin(); 770 Kind = ScopeKind::NestedAttribute; 771 } 772 JOS.attributeBegin(Label); 773 scopedBegin({Ctx, Kind}); 774 } 775 776 void scopedEnd() { 777 ScopeContext ScopeCtx = ScopeHistory.back(); 778 if (ScopeCtx.Context == Scope::Object) 779 JOS.objectEnd(); 780 else if (ScopeCtx.Context == Scope::Array) 781 JOS.arrayEnd(); 782 if (ScopeCtx.Kind == ScopeKind::Attribute || 783 ScopeCtx.Kind == ScopeKind::NestedAttribute) 784 JOS.attributeEnd(); 785 if (ScopeCtx.Kind == ScopeKind::NestedAttribute) 786 JOS.objectEnd(); 787 ScopeHistory.pop_back(); 788 } 789 }; 790 791 struct DelimitedScope { 792 DelimitedScope(ScopedPrinter &W) : W(&W) {} 793 DelimitedScope() : W(nullptr) {} 794 virtual ~DelimitedScope() = default; 795 virtual void setPrinter(ScopedPrinter &W) = 0; 796 ScopedPrinter *W; 797 }; 798 799 struct DictScope : DelimitedScope { 800 explicit DictScope() = default; 801 explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); } 802 803 DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) { 804 W.objectBegin(N); 805 } 806 807 void setPrinter(ScopedPrinter &W) override { 808 this->W = &W; 809 W.objectBegin(); 810 } 811 812 ~DictScope() { 813 if (W) 814 W->objectEnd(); 815 } 816 }; 817 818 struct ListScope : DelimitedScope { 819 explicit ListScope() = default; 820 explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); } 821 822 ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) { 823 W.arrayBegin(N); 824 } 825 826 void setPrinter(ScopedPrinter &W) override { 827 this->W = &W; 828 W.arrayBegin(); 829 } 830 831 ~ListScope() { 832 if (W) 833 W->arrayEnd(); 834 } 835 }; 836 837 } // namespace llvm 838 839 #endif 840