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 #include <algorithm> 22 23 namespace llvm { 24 25 template <typename T> struct EnumEntry { 26 StringRef Name; 27 // While Name suffices in most of the cases, in certain cases 28 // GNU style and LLVM style of ELFDumper do not 29 // display same string for same enum. The AltName if initialized appropriately 30 // will hold the string that GNU style emits. 31 // Example: 32 // "EM_X86_64" string on LLVM style for Elf_Ehdr->e_machine corresponds to 33 // "Advanced Micro Devices X86-64" on GNU style 34 StringRef AltName; 35 T Value; 36 constexpr EnumEntry(StringRef N, StringRef A, T V) 37 : Name(N), AltName(A), Value(V) {} 38 constexpr EnumEntry(StringRef N, T V) : Name(N), AltName(N), Value(V) {} 39 }; 40 41 struct HexNumber { 42 // To avoid sign-extension we have to explicitly cast to the appropriate 43 // unsigned type. The overloads are here so that every type that is implicitly 44 // convertible to an integer (including enums and endian helpers) can be used 45 // without requiring type traits or call-site changes. 46 HexNumber(char Value) : Value(static_cast<unsigned char>(Value)) {} 47 HexNumber(signed char Value) : Value(static_cast<unsigned char>(Value)) {} 48 HexNumber(signed short Value) : Value(static_cast<unsigned short>(Value)) {} 49 HexNumber(signed int Value) : Value(static_cast<unsigned int>(Value)) {} 50 HexNumber(signed long Value) : Value(static_cast<unsigned long>(Value)) {} 51 HexNumber(signed long long Value) 52 : Value(static_cast<unsigned long long>(Value)) {} 53 HexNumber(unsigned char Value) : Value(Value) {} 54 HexNumber(unsigned short Value) : Value(Value) {} 55 HexNumber(unsigned int Value) : Value(Value) {} 56 HexNumber(unsigned long Value) : Value(Value) {} 57 HexNumber(unsigned long long Value) : Value(Value) {} 58 uint64_t Value; 59 }; 60 61 struct FlagEntry { 62 FlagEntry(StringRef Name, char Value) 63 : Name(Name), Value(static_cast<unsigned char>(Value)) {} 64 FlagEntry(StringRef Name, signed char Value) 65 : Name(Name), Value(static_cast<unsigned char>(Value)) {} 66 FlagEntry(StringRef Name, signed short Value) 67 : Name(Name), Value(static_cast<unsigned short>(Value)) {} 68 FlagEntry(StringRef Name, signed int Value) 69 : Name(Name), Value(static_cast<unsigned int>(Value)) {} 70 FlagEntry(StringRef Name, signed long Value) 71 : Name(Name), Value(static_cast<unsigned long>(Value)) {} 72 FlagEntry(StringRef Name, signed long long Value) 73 : Name(Name), Value(static_cast<unsigned long long>(Value)) {} 74 FlagEntry(StringRef Name, unsigned char Value) : Name(Name), Value(Value) {} 75 FlagEntry(StringRef Name, unsigned short Value) : Name(Name), Value(Value) {} 76 FlagEntry(StringRef Name, unsigned int Value) : Name(Name), Value(Value) {} 77 FlagEntry(StringRef Name, unsigned long Value) : Name(Name), Value(Value) {} 78 FlagEntry(StringRef Name, unsigned long long Value) 79 : Name(Name), Value(Value) {} 80 StringRef Name; 81 uint64_t Value; 82 }; 83 84 raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value); 85 std::string to_hexString(uint64_t Value, bool UpperCase = true); 86 87 template <class T> std::string to_string(const T &Value) { 88 std::string number; 89 raw_string_ostream stream(number); 90 stream << Value; 91 return stream.str(); 92 } 93 94 template <typename T, typename TEnum> 95 std::string enumToString(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) { 96 for (const EnumEntry<TEnum> &EnumItem : EnumValues) 97 if (EnumItem.Value == Value) 98 return std::string(EnumItem.AltName); 99 return to_hexString(Value, false); 100 } 101 102 class ScopedPrinter { 103 public: 104 enum class ScopedPrinterKind { 105 Base, 106 JSON, 107 }; 108 109 ScopedPrinter(raw_ostream &OS, 110 ScopedPrinterKind Kind = ScopedPrinterKind::Base) 111 : OS(OS), IndentLevel(0), Kind(Kind) {} 112 113 ScopedPrinterKind getKind() const { return Kind; } 114 115 static bool classof(const ScopedPrinter *SP) { 116 return SP->getKind() == ScopedPrinterKind::Base; 117 } 118 119 virtual ~ScopedPrinter() {} 120 121 void flush() { OS.flush(); } 122 123 void indent(int Levels = 1) { IndentLevel += Levels; } 124 125 void unindent(int Levels = 1) { 126 IndentLevel = std::max(0, IndentLevel - Levels); 127 } 128 129 void resetIndent() { IndentLevel = 0; } 130 131 int getIndentLevel() { return IndentLevel; } 132 133 void setPrefix(StringRef P) { Prefix = P; } 134 135 void printIndent() { 136 OS << Prefix; 137 for (int i = 0; i < IndentLevel; ++i) 138 OS << " "; 139 } 140 141 template <typename T> HexNumber hex(T Value) { return HexNumber(Value); } 142 143 template <typename T, typename TEnum> 144 void printEnum(StringRef Label, T Value, 145 ArrayRef<EnumEntry<TEnum>> EnumValues) { 146 StringRef Name; 147 bool Found = false; 148 for (const auto &EnumItem : EnumValues) { 149 if (EnumItem.Value == Value) { 150 Name = EnumItem.Name; 151 Found = true; 152 break; 153 } 154 } 155 156 if (Found) 157 printHex(Label, Name, Value); 158 else 159 printHex(Label, Value); 160 } 161 162 template <typename T, typename TFlag> 163 void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags, 164 TFlag EnumMask1 = {}, TFlag EnumMask2 = {}, 165 TFlag EnumMask3 = {}) { 166 SmallVector<FlagEntry, 10> SetFlags; 167 168 for (const auto &Flag : Flags) { 169 if (Flag.Value == 0) 170 continue; 171 172 TFlag EnumMask{}; 173 if (Flag.Value & EnumMask1) 174 EnumMask = EnumMask1; 175 else if (Flag.Value & EnumMask2) 176 EnumMask = EnumMask2; 177 else if (Flag.Value & EnumMask3) 178 EnumMask = EnumMask3; 179 bool IsEnum = (Flag.Value & EnumMask) != 0; 180 if ((!IsEnum && (Value & Flag.Value) == Flag.Value) || 181 (IsEnum && (Value & EnumMask) == Flag.Value)) { 182 SetFlags.emplace_back(Flag.Name, Flag.Value); 183 } 184 } 185 186 llvm::sort(SetFlags, &flagName); 187 printFlagsImpl(Label, hex(Value), SetFlags); 188 } 189 190 template <typename T> void printFlags(StringRef Label, T Value) { 191 SmallVector<HexNumber, 10> SetFlags; 192 uint64_t Flag = 1; 193 uint64_t Curr = Value; 194 while (Curr > 0) { 195 if (Curr & 1) 196 SetFlags.emplace_back(Flag); 197 Curr >>= 1; 198 Flag <<= 1; 199 } 200 printFlagsImpl(Label, hex(Value), SetFlags); 201 } 202 203 virtual void printNumber(StringRef Label, uint64_t Value) { 204 startLine() << Label << ": " << Value << "\n"; 205 } 206 207 virtual void printNumber(StringRef Label, uint32_t Value) { 208 startLine() << Label << ": " << Value << "\n"; 209 } 210 211 virtual void printNumber(StringRef Label, uint16_t Value) { 212 startLine() << Label << ": " << Value << "\n"; 213 } 214 215 virtual void printNumber(StringRef Label, uint8_t Value) { 216 startLine() << Label << ": " << unsigned(Value) << "\n"; 217 } 218 219 virtual void printNumber(StringRef Label, int64_t Value) { 220 startLine() << Label << ": " << Value << "\n"; 221 } 222 223 virtual void printNumber(StringRef Label, int32_t Value) { 224 startLine() << Label << ": " << Value << "\n"; 225 } 226 227 virtual void printNumber(StringRef Label, int16_t Value) { 228 startLine() << Label << ": " << Value << "\n"; 229 } 230 231 virtual void printNumber(StringRef Label, int8_t Value) { 232 startLine() << Label << ": " << int(Value) << "\n"; 233 } 234 235 virtual void printNumber(StringRef Label, const APSInt &Value) { 236 startLine() << Label << ": " << Value << "\n"; 237 } 238 239 template <typename T> 240 void printNumber(StringRef Label, StringRef Str, T Value) { 241 printNumberImpl(Label, Str, to_string(Value)); 242 } 243 244 virtual void printBoolean(StringRef Label, bool Value) { 245 startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n'; 246 } 247 248 template <typename... T> void printVersion(StringRef Label, T... Version) { 249 startLine() << Label << ": "; 250 printVersionInternal(Version...); 251 getOStream() << "\n"; 252 } 253 254 template <typename T> 255 void printList(StringRef Label, const ArrayRef<T> List) { 256 SmallVector<std::string, 10> StringList; 257 for (const auto &Item : List) 258 StringList.emplace_back(to_string(Item)); 259 printList(Label, StringList); 260 } 261 262 virtual void printList(StringRef Label, const ArrayRef<bool> List) { 263 printListImpl(Label, List); 264 } 265 266 virtual void printList(StringRef Label, const ArrayRef<std::string> List) { 267 printListImpl(Label, List); 268 } 269 270 virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) { 271 printListImpl(Label, List); 272 } 273 274 virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) { 275 printListImpl(Label, List); 276 } 277 278 virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) { 279 printListImpl(Label, List); 280 } 281 282 virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) { 283 SmallVector<unsigned> NumberList; 284 for (const uint8_t &Item : List) 285 NumberList.emplace_back(Item); 286 printListImpl(Label, NumberList); 287 } 288 289 virtual void printList(StringRef Label, const ArrayRef<int64_t> List) { 290 printListImpl(Label, List); 291 } 292 293 virtual void printList(StringRef Label, const ArrayRef<int32_t> List) { 294 printListImpl(Label, List); 295 } 296 297 virtual void printList(StringRef Label, const ArrayRef<int16_t> List) { 298 printListImpl(Label, List); 299 } 300 301 virtual void printList(StringRef Label, const ArrayRef<int8_t> List) { 302 SmallVector<int> NumberList; 303 for (const int8_t &Item : List) 304 NumberList.emplace_back(Item); 305 printListImpl(Label, NumberList); 306 } 307 308 virtual void printList(StringRef Label, const ArrayRef<APSInt> List) { 309 printListImpl(Label, List); 310 } 311 312 template <typename T, typename U> 313 void printList(StringRef Label, const T &List, const U &Printer) { 314 startLine() << Label << ": ["; 315 ListSeparator LS; 316 for (const auto &Item : List) { 317 OS << LS; 318 Printer(OS, Item); 319 } 320 OS << "]\n"; 321 } 322 323 template <typename T> void printHexList(StringRef Label, const T &List) { 324 SmallVector<HexNumber> HexList; 325 for (const auto &Item : List) 326 HexList.emplace_back(Item); 327 printHexListImpl(Label, HexList); 328 } 329 330 template <typename T> void printHex(StringRef Label, T Value) { 331 printHexImpl(Label, hex(Value)); 332 } 333 334 template <typename T> void printHex(StringRef Label, StringRef Str, T Value) { 335 printHexImpl(Label, Str, hex(Value)); 336 } 337 338 template <typename T> 339 void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) { 340 printSymbolOffsetImpl(Label, Symbol, hex(Value)); 341 } 342 343 virtual void printString(StringRef Value) { startLine() << Value << "\n"; } 344 345 virtual void printString(StringRef Label, StringRef Value) { 346 startLine() << Label << ": " << Value << "\n"; 347 } 348 349 void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) { 350 printBinaryImpl(Label, Str, Value, false); 351 } 352 353 void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) { 354 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 355 Value.size()); 356 printBinaryImpl(Label, Str, V, false); 357 } 358 359 void printBinary(StringRef Label, ArrayRef<uint8_t> Value) { 360 printBinaryImpl(Label, StringRef(), Value, false); 361 } 362 363 void printBinary(StringRef Label, ArrayRef<char> Value) { 364 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 365 Value.size()); 366 printBinaryImpl(Label, StringRef(), V, false); 367 } 368 369 void printBinary(StringRef Label, StringRef Value) { 370 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 371 Value.size()); 372 printBinaryImpl(Label, StringRef(), V, false); 373 } 374 375 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value, 376 uint32_t StartOffset) { 377 printBinaryImpl(Label, StringRef(), Value, true, StartOffset); 378 } 379 380 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) { 381 printBinaryImpl(Label, StringRef(), Value, true); 382 } 383 384 void printBinaryBlock(StringRef Label, StringRef Value) { 385 auto V = makeArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), 386 Value.size()); 387 printBinaryImpl(Label, StringRef(), V, true); 388 } 389 390 template <typename T> void printObject(StringRef Label, const T &Value) { 391 printString(Label, to_string(Value)); 392 } 393 394 virtual void objectBegin() { scopedBegin('{'); } 395 396 virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); } 397 398 virtual void objectEnd() { scopedEnd('}'); } 399 400 virtual void arrayBegin() { scopedBegin('['); } 401 402 virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); } 403 404 virtual void arrayEnd() { scopedEnd(']'); } 405 406 virtual raw_ostream &startLine() { 407 printIndent(); 408 return OS; 409 } 410 411 virtual raw_ostream &getOStream() { return OS; } 412 413 private: 414 template <typename T> void printVersionInternal(T Value) { 415 getOStream() << Value; 416 } 417 418 template <typename S, typename T, typename... TArgs> 419 void printVersionInternal(S Value, T Value2, TArgs... Args) { 420 getOStream() << Value << "."; 421 printVersionInternal(Value2, Args...); 422 } 423 424 static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) { 425 return LHS.Name < RHS.Name; 426 } 427 428 virtual void printBinaryImpl(StringRef Label, StringRef Str, 429 ArrayRef<uint8_t> Value, bool Block, 430 uint32_t StartOffset = 0); 431 432 virtual void printFlagsImpl(StringRef Label, HexNumber Value, 433 ArrayRef<FlagEntry> Flags) { 434 startLine() << Label << " [ (" << Value << ")\n"; 435 for (const auto &Flag : Flags) 436 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n"; 437 startLine() << "]\n"; 438 } 439 440 virtual void printFlagsImpl(StringRef Label, HexNumber Value, 441 ArrayRef<HexNumber> Flags) { 442 startLine() << Label << " [ (" << Value << ")\n"; 443 for (const auto &Flag : Flags) 444 startLine() << " " << Flag << '\n'; 445 startLine() << "]\n"; 446 } 447 448 template <typename T> void printListImpl(StringRef Label, const T List) { 449 startLine() << Label << ": ["; 450 ListSeparator LS; 451 for (const auto &Item : List) 452 OS << LS << Item; 453 OS << "]\n"; 454 } 455 456 virtual void printHexListImpl(StringRef Label, 457 const ArrayRef<HexNumber> List) { 458 startLine() << Label << ": ["; 459 ListSeparator LS; 460 for (const auto &Item : List) 461 OS << LS << hex(Item); 462 OS << "]\n"; 463 } 464 465 virtual void printHexImpl(StringRef Label, HexNumber Value) { 466 startLine() << Label << ": " << Value << "\n"; 467 } 468 469 virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) { 470 startLine() << Label << ": " << Str << " (" << Value << ")\n"; 471 } 472 473 virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol, 474 HexNumber Value) { 475 startLine() << Label << ": " << Symbol << '+' << Value << '\n'; 476 } 477 478 virtual void printNumberImpl(StringRef Label, StringRef Str, 479 StringRef Value) { 480 startLine() << Label << ": " << Str << " (" << Value << ")\n"; 481 } 482 483 void scopedBegin(char Symbol) { 484 startLine() << Symbol << '\n'; 485 indent(); 486 } 487 488 void scopedBegin(StringRef Label, char Symbol) { 489 startLine() << Label; 490 if (!Label.empty()) 491 OS << ' '; 492 OS << Symbol << '\n'; 493 indent(); 494 } 495 496 void scopedEnd(char Symbol) { 497 unindent(); 498 startLine() << Symbol << '\n'; 499 } 500 501 raw_ostream &OS; 502 int IndentLevel; 503 StringRef Prefix; 504 ScopedPrinterKind Kind; 505 }; 506 507 template <> 508 inline void 509 ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label, 510 support::ulittle16_t Value) { 511 startLine() << Label << ": " << hex(Value) << "\n"; 512 } 513 514 struct DelimitedScope; 515 516 class JSONScopedPrinter : public ScopedPrinter { 517 private: 518 enum class Scope { 519 Array, 520 Object, 521 }; 522 523 enum class ScopeKind { 524 NoAttribute, 525 Attribute, 526 NestedAttribute, 527 }; 528 529 struct ScopeContext { 530 Scope Context; 531 ScopeKind Kind; 532 ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute) 533 : Context(Context), Kind(Kind) {} 534 }; 535 536 SmallVector<ScopeContext, 8> ScopeHistory; 537 json::OStream JOS; 538 std::unique_ptr<DelimitedScope> OuterScope; 539 540 public: 541 JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false, 542 std::unique_ptr<DelimitedScope> &&OuterScope = 543 std::unique_ptr<DelimitedScope>{}); 544 545 static bool classof(const ScopedPrinter *SP) { 546 return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON; 547 } 548 549 void printNumber(StringRef Label, uint64_t Value) override { 550 JOS.attribute(Label, Value); 551 } 552 553 void printNumber(StringRef Label, uint32_t Value) override { 554 JOS.attribute(Label, Value); 555 } 556 557 void printNumber(StringRef Label, uint16_t Value) override { 558 JOS.attribute(Label, Value); 559 } 560 561 void printNumber(StringRef Label, uint8_t Value) override { 562 JOS.attribute(Label, Value); 563 } 564 565 void printNumber(StringRef Label, int64_t Value) override { 566 JOS.attribute(Label, Value); 567 } 568 569 void printNumber(StringRef Label, int32_t Value) override { 570 JOS.attribute(Label, Value); 571 } 572 573 void printNumber(StringRef Label, int16_t Value) override { 574 JOS.attribute(Label, Value); 575 } 576 577 void printNumber(StringRef Label, int8_t Value) override { 578 JOS.attribute(Label, Value); 579 } 580 581 void printNumber(StringRef Label, const APSInt &Value) override { 582 JOS.attributeBegin(Label); 583 printAPSInt(Value); 584 JOS.attributeEnd(); 585 } 586 587 void printBoolean(StringRef Label, bool Value) override { 588 JOS.attribute(Label, Value); 589 } 590 591 void printList(StringRef Label, const ArrayRef<bool> List) override { 592 printListImpl(Label, List); 593 } 594 595 void printList(StringRef Label, const ArrayRef<std::string> List) override { 596 printListImpl(Label, List); 597 } 598 599 void printList(StringRef Label, const ArrayRef<uint64_t> List) override { 600 printListImpl(Label, List); 601 } 602 603 void printList(StringRef Label, const ArrayRef<uint32_t> List) override { 604 printListImpl(Label, List); 605 } 606 607 void printList(StringRef Label, const ArrayRef<uint16_t> List) override { 608 printListImpl(Label, List); 609 } 610 611 void printList(StringRef Label, const ArrayRef<uint8_t> List) override { 612 printListImpl(Label, List); 613 } 614 615 void printList(StringRef Label, const ArrayRef<int64_t> List) override { 616 printListImpl(Label, List); 617 } 618 619 void printList(StringRef Label, const ArrayRef<int32_t> List) override { 620 printListImpl(Label, List); 621 } 622 623 void printList(StringRef Label, const ArrayRef<int16_t> List) override { 624 printListImpl(Label, List); 625 } 626 627 void printList(StringRef Label, const ArrayRef<int8_t> List) override { 628 printListImpl(Label, List); 629 } 630 631 void printList(StringRef Label, const ArrayRef<APSInt> List) override { 632 JOS.attributeArray(Label, [&]() { 633 for (const APSInt &Item : List) { 634 printAPSInt(Item); 635 } 636 }); 637 } 638 639 void printString(StringRef Value) override { JOS.value(Value); } 640 641 void printString(StringRef Label, StringRef Value) override { 642 JOS.attribute(Label, Value); 643 } 644 645 void objectBegin() override { 646 scopedBegin({Scope::Object, ScopeKind::NoAttribute}); 647 } 648 649 void objectBegin(StringRef Label) override { 650 scopedBegin(Label, Scope::Object); 651 } 652 653 void objectEnd() override { scopedEnd(); } 654 655 void arrayBegin() override { 656 scopedBegin({Scope::Array, ScopeKind::NoAttribute}); 657 } 658 659 void arrayBegin(StringRef Label) override { 660 scopedBegin(Label, Scope::Array); 661 } 662 663 void arrayEnd() override { scopedEnd(); } 664 665 private: 666 // Output HexNumbers as decimals so that they're easier to parse. 667 uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; } 668 669 void printAPSInt(const APSInt &Value) { 670 JOS.rawValueBegin() << Value; 671 JOS.rawValueEnd(); 672 } 673 674 void printFlagsImpl(StringRef Label, HexNumber Value, 675 ArrayRef<FlagEntry> Flags) override { 676 JOS.attributeObject(Label, [&]() { 677 JOS.attribute("RawFlags", hexNumberToInt(Value)); 678 JOS.attributeArray("Flags", [&]() { 679 for (const FlagEntry &Flag : Flags) { 680 JOS.objectBegin(); 681 JOS.attribute("Name", Flag.Name); 682 JOS.attribute("Value", Flag.Value); 683 JOS.objectEnd(); 684 } 685 }); 686 }); 687 } 688 689 void printFlagsImpl(StringRef Label, HexNumber Value, 690 ArrayRef<HexNumber> Flags) override { 691 JOS.attributeObject(Label, [&]() { 692 JOS.attribute("RawFlags", hexNumberToInt(Value)); 693 JOS.attributeArray("Flags", [&]() { 694 for (const HexNumber &Flag : Flags) { 695 JOS.value(Flag.Value); 696 } 697 }); 698 }); 699 } 700 701 template <typename T> void printListImpl(StringRef Label, const T &List) { 702 JOS.attributeArray(Label, [&]() { 703 for (const auto &Item : List) 704 JOS.value(Item); 705 }); 706 } 707 708 void printHexListImpl(StringRef Label, 709 const ArrayRef<HexNumber> List) override { 710 JOS.attributeArray(Label, [&]() { 711 for (const HexNumber &Item : List) { 712 JOS.value(hexNumberToInt(Item)); 713 } 714 }); 715 } 716 717 void printHexImpl(StringRef Label, HexNumber Value) override { 718 JOS.attribute(Label, hexNumberToInt(Value)); 719 } 720 721 void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override { 722 JOS.attributeObject(Label, [&]() { 723 JOS.attribute("Value", Str); 724 JOS.attribute("RawValue", hexNumberToInt(Value)); 725 }); 726 } 727 728 void printSymbolOffsetImpl(StringRef Label, StringRef Symbol, 729 HexNumber Value) override { 730 JOS.attributeObject(Label, [&]() { 731 JOS.attribute("SymName", Symbol); 732 JOS.attribute("Offset", hexNumberToInt(Value)); 733 }); 734 } 735 736 void printNumberImpl(StringRef Label, StringRef Str, 737 StringRef Value) override { 738 JOS.attributeObject(Label, [&]() { 739 JOS.attribute("Value", Str); 740 JOS.attributeBegin("RawValue"); 741 JOS.rawValueBegin() << Value; 742 JOS.rawValueEnd(); 743 JOS.attributeEnd(); 744 }); 745 } 746 747 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value, 748 bool Block, uint32_t StartOffset = 0) override { 749 JOS.attributeObject(Label, [&]() { 750 if (!Str.empty()) 751 JOS.attribute("Value", Str); 752 JOS.attribute("Offset", StartOffset); 753 JOS.attributeArray("Bytes", [&]() { 754 for (uint8_t Val : Value) 755 JOS.value(Val); 756 }); 757 }); 758 } 759 760 void scopedBegin(ScopeContext ScopeCtx) { 761 if (ScopeCtx.Context == Scope::Object) 762 JOS.objectBegin(); 763 else if (ScopeCtx.Context == Scope::Array) 764 JOS.arrayBegin(); 765 ScopeHistory.push_back(ScopeCtx); 766 } 767 768 void scopedBegin(StringRef Label, Scope Ctx) { 769 ScopeKind Kind = ScopeKind::Attribute; 770 if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) { 771 JOS.objectBegin(); 772 Kind = ScopeKind::NestedAttribute; 773 } 774 JOS.attributeBegin(Label); 775 scopedBegin({Ctx, Kind}); 776 } 777 778 void scopedEnd() { 779 ScopeContext ScopeCtx = ScopeHistory.back(); 780 if (ScopeCtx.Context == Scope::Object) 781 JOS.objectEnd(); 782 else if (ScopeCtx.Context == Scope::Array) 783 JOS.arrayEnd(); 784 if (ScopeCtx.Kind == ScopeKind::Attribute || 785 ScopeCtx.Kind == ScopeKind::NestedAttribute) 786 JOS.attributeEnd(); 787 if (ScopeCtx.Kind == ScopeKind::NestedAttribute) 788 JOS.objectEnd(); 789 ScopeHistory.pop_back(); 790 } 791 }; 792 793 struct DelimitedScope { 794 DelimitedScope(ScopedPrinter &W) : W(&W) {} 795 DelimitedScope() : W(nullptr) {} 796 virtual ~DelimitedScope(){}; 797 virtual void setPrinter(ScopedPrinter &W) = 0; 798 ScopedPrinter *W; 799 }; 800 801 struct DictScope : DelimitedScope { 802 explicit DictScope() : DelimitedScope() {} 803 explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); } 804 805 DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) { 806 W.objectBegin(N); 807 } 808 809 void setPrinter(ScopedPrinter &W) override { 810 this->W = &W; 811 W.objectBegin(); 812 } 813 814 ~DictScope() { 815 if (W) 816 W->objectEnd(); 817 } 818 }; 819 820 struct ListScope : DelimitedScope { 821 explicit ListScope() : DelimitedScope() {} 822 explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); } 823 824 ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) { 825 W.arrayBegin(N); 826 } 827 828 void setPrinter(ScopedPrinter &W) override { 829 this->W = &W; 830 W.arrayBegin(); 831 } 832 833 ~ListScope() { 834 if (W) 835 W->arrayEnd(); 836 } 837 }; 838 839 } // namespace llvm 840 841 #endif 842