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 22namespace llvm { 23 24template <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 40struct 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 60struct 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 83raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value); 84 85template <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 92template <typename T, typename TEnum> 93std::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 100class ScopedPrinter { 101public: 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, char Value) { 202 startLine() << Label << ": " << static_cast<int>(Value) << "\n"; 203 } 204 205 virtual void printNumber(StringRef Label, signed char Value) { 206 startLine() << Label << ": " << static_cast<int>(Value) << "\n"; 207 } 208 209 virtual void printNumber(StringRef Label, unsigned char Value) { 210 startLine() << Label << ": " << static_cast<unsigned>(Value) << "\n"; 211 } 212 213 virtual void printNumber(StringRef Label, short Value) { 214 startLine() << Label << ": " << Value << "\n"; 215 } 216 217 virtual void printNumber(StringRef Label, unsigned short Value) { 218 startLine() << Label << ": " << Value << "\n"; 219 } 220 221 virtual void printNumber(StringRef Label, int Value) { 222 startLine() << Label << ": " << Value << "\n"; 223 } 224 225 virtual void printNumber(StringRef Label, unsigned int Value) { 226 startLine() << Label << ": " << Value << "\n"; 227 } 228 229 virtual void printNumber(StringRef Label, long Value) { 230 startLine() << Label << ": " << Value << "\n"; 231 } 232 233 virtual void printNumber(StringRef Label, unsigned long Value) { 234 startLine() << Label << ": " << Value << "\n"; 235 } 236 237 virtual void printNumber(StringRef Label, long long Value) { 238 startLine() << Label << ": " << Value << "\n"; 239 } 240 241 virtual void printNumber(StringRef Label, unsigned long long Value) { 242 startLine() << Label << ": " << Value << "\n"; 243 } 244 245 virtual void printNumber(StringRef Label, const APSInt &Value) { 246 startLine() << Label << ": " << Value << "\n"; 247 } 248 249 virtual void printNumber(StringRef Label, float Value) { 250 startLine() << Label << ": " << format("%5.1f", Value) << "\n"; 251 } 252 253 virtual void printNumber(StringRef Label, double Value) { 254 startLine() << Label << ": " << format("%5.1f", Value) << "\n"; 255 } 256 257 template <typename T> 258 void printNumber(StringRef Label, StringRef Str, T Value) { 259 printNumberImpl(Label, Str, to_string(Value)); 260 } 261 262 virtual void printBoolean(StringRef Label, bool Value) { 263 startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n'; 264 } 265 266 template <typename... T> void printVersion(StringRef Label, T... Version) { 267 startLine() << Label << ": "; 268 printVersionInternal(Version...); 269 getOStream() << "\n"; 270 } 271 272 template <typename T> 273 void printList(StringRef Label, const ArrayRef<T> List) { 274 SmallVector<std::string, 10> StringList; 275 for (const auto &Item : List) 276 StringList.emplace_back(to_string(Item)); 277 printList(Label, StringList); 278 } 279 280 virtual void printList(StringRef Label, const ArrayRef<bool> List) { 281 printListImpl(Label, List); 282 } 283 284 virtual void printList(StringRef Label, const ArrayRef<std::string> List) { 285 printListImpl(Label, List); 286 } 287 288 virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) { 289 printListImpl(Label, List); 290 } 291 292 virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) { 293 printListImpl(Label, List); 294 } 295 296 virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) { 297 printListImpl(Label, List); 298 } 299 300 virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) { 301 SmallVector<unsigned> NumberList; 302 for (const uint8_t &Item : List) 303 NumberList.emplace_back(Item); 304 printListImpl(Label, NumberList); 305 } 306 307 virtual void printList(StringRef Label, const ArrayRef<int64_t> List) { 308 printListImpl(Label, List); 309 } 310 311 virtual void printList(StringRef Label, const ArrayRef<int32_t> List) { 312 printListImpl(Label, List); 313 } 314 315 virtual void printList(StringRef Label, const ArrayRef<int16_t> List) { 316 printListImpl(Label, List); 317 } 318 319 virtual void printList(StringRef Label, const ArrayRef<int8_t> List) { 320 SmallVector<int> NumberList; 321 for (const int8_t &Item : List) 322 NumberList.emplace_back(Item); 323 printListImpl(Label, NumberList); 324 } 325 326 virtual void printList(StringRef Label, const ArrayRef<APSInt> List) { 327 printListImpl(Label, List); 328 } 329 330 template <typename T, typename U> 331 void printList(StringRef Label, const T &List, const U &Printer) { 332 startLine() << Label << ": ["; 333 ListSeparator LS; 334 for (const auto &Item : List) { 335 OS << LS; 336 Printer(OS, Item); 337 } 338 OS << "]\n"; 339 } 340 341 template <typename T> void printHexList(StringRef Label, const T &List) { 342 SmallVector<HexNumber> HexList; 343 for (const auto &Item : List) 344 HexList.emplace_back(Item); 345 printHexListImpl(Label, HexList); 346 } 347 348 template <typename T> void printHex(StringRef Label, T Value) { 349 printHexImpl(Label, hex(Value)); 350 } 351 352 template <typename T> void printHex(StringRef Label, StringRef Str, T Value) { 353 printHexImpl(Label, Str, hex(Value)); 354 } 355 356 template <typename T> 357 void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) { 358 printSymbolOffsetImpl(Label, Symbol, hex(Value)); 359 } 360 361 virtual void printString(StringRef Value) { startLine() << Value << "\n"; } 362 363 virtual void printString(StringRef Label, StringRef Value) { 364 startLine() << Label << ": " << Value << "\n"; 365 } 366 367 void printStringEscaped(StringRef Label, StringRef Value) { 368 printStringEscapedImpl(Label, Value); 369 } 370 371 void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) { 372 printBinaryImpl(Label, Str, Value, false); 373 } 374 375 void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) { 376 auto V = 377 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size()); 378 printBinaryImpl(Label, Str, V, false); 379 } 380 381 void printBinary(StringRef Label, ArrayRef<uint8_t> Value) { 382 printBinaryImpl(Label, StringRef(), Value, false); 383 } 384 385 void printBinary(StringRef Label, ArrayRef<char> Value) { 386 auto V = 387 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size()); 388 printBinaryImpl(Label, StringRef(), V, false); 389 } 390 391 void printBinary(StringRef Label, StringRef Value) { 392 auto V = 393 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size()); 394 printBinaryImpl(Label, StringRef(), V, false); 395 } 396 397 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value, 398 uint32_t StartOffset) { 399 printBinaryImpl(Label, StringRef(), Value, true, StartOffset); 400 } 401 402 void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) { 403 printBinaryImpl(Label, StringRef(), Value, true); 404 } 405 406 void printBinaryBlock(StringRef Label, StringRef Value) { 407 auto V = 408 ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size()); 409 printBinaryImpl(Label, StringRef(), V, true); 410 } 411 412 template <typename T> void printObject(StringRef Label, const T &Value) { 413 printString(Label, to_string(Value)); 414 } 415 416 virtual void objectBegin() { scopedBegin('{'); } 417 418 virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); } 419 420 virtual void objectEnd() { scopedEnd('}'); } 421 422 virtual void arrayBegin() { scopedBegin('['); } 423 424 virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); } 425 426 virtual void arrayEnd() { scopedEnd(']'); } 427 428 virtual raw_ostream &startLine() { 429 printIndent(); 430 return OS; 431 } 432 433 virtual raw_ostream &getOStream() { return OS; } 434 435private: 436 template <typename T> void printVersionInternal(T Value) { 437 getOStream() << Value; 438 } 439 440 template <typename S, typename T, typename... TArgs> 441 void printVersionInternal(S Value, T Value2, TArgs... Args) { 442 getOStream() << Value << "."; 443 printVersionInternal(Value2, Args...); 444 } 445 446 static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) { 447 return LHS.Name < RHS.Name; 448 } 449 450 virtual void printBinaryImpl(StringRef Label, StringRef Str, 451 ArrayRef<uint8_t> Value, bool Block, 452 uint32_t StartOffset = 0); 453 454 virtual void printFlagsImpl(StringRef Label, HexNumber Value, 455 ArrayRef<FlagEntry> Flags) { 456 startLine() << Label << " [ (" << Value << ")\n"; 457 for (const auto &Flag : Flags) 458 startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n"; 459 startLine() << "]\n"; 460 } 461 462 virtual void printFlagsImpl(StringRef Label, HexNumber Value, 463 ArrayRef<HexNumber> Flags) { 464 startLine() << Label << " [ (" << Value << ")\n"; 465 for (const auto &Flag : Flags) 466 startLine() << " " << Flag << '\n'; 467 startLine() << "]\n"; 468 } 469 470 template <typename T> void printListImpl(StringRef Label, const T List) { 471 startLine() << Label << ": ["; 472 ListSeparator LS; 473 for (const auto &Item : List) 474 OS << LS << Item; 475 OS << "]\n"; 476 } 477 478 virtual void printHexListImpl(StringRef Label, 479 const ArrayRef<HexNumber> List) { 480 startLine() << Label << ": ["; 481 ListSeparator LS; 482 for (const auto &Item : List) 483 OS << LS << hex(Item); 484 OS << "]\n"; 485 } 486 487 virtual void printHexImpl(StringRef Label, HexNumber Value) { 488 startLine() << Label << ": " << Value << "\n"; 489 } 490 491 virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) { 492 startLine() << Label << ": " << Str << " (" << Value << ")\n"; 493 } 494 495 virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol, 496 HexNumber Value) { 497 startLine() << Label << ": " << Symbol << '+' << Value << '\n'; 498 } 499 500 virtual void printNumberImpl(StringRef Label, StringRef Str, 501 StringRef Value) { 502 startLine() << Label << ": " << Str << " (" << Value << ")\n"; 503 } 504 505 virtual void printStringEscapedImpl(StringRef Label, StringRef Value) { 506 startLine() << Label << ": "; 507 OS.write_escaped(Value); 508 OS << '\n'; 509 } 510 511 void scopedBegin(char Symbol) { 512 startLine() << Symbol << '\n'; 513 indent(); 514 } 515 516 void scopedBegin(StringRef Label, char Symbol) { 517 startLine() << Label; 518 if (!Label.empty()) 519 OS << ' '; 520 OS << Symbol << '\n'; 521 indent(); 522 } 523 524 void scopedEnd(char Symbol) { 525 unindent(); 526 startLine() << Symbol << '\n'; 527 } 528 529 raw_ostream &OS; 530 int IndentLevel = 0; 531 StringRef Prefix; 532 ScopedPrinterKind Kind; 533}; 534 535template <> 536inline void 537ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label, 538 support::ulittle16_t Value) { 539 startLine() << Label << ": " << hex(Value) << "\n"; 540} 541 542struct DelimitedScope; 543 544class JSONScopedPrinter : public ScopedPrinter { 545private: 546 enum class Scope { 547 Array, 548 Object, 549 }; 550 551 enum class ScopeKind { 552 NoAttribute, 553 Attribute, 554 NestedAttribute, 555 }; 556 557 struct ScopeContext { 558 Scope Context; 559 ScopeKind Kind; 560 ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute) 561 : Context(Context), Kind(Kind) {} 562 }; 563 564 SmallVector<ScopeContext, 8> ScopeHistory; 565 json::OStream JOS; 566 std::unique_ptr<DelimitedScope> OuterScope; 567 568public: 569 JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false, 570 std::unique_ptr<DelimitedScope> &&OuterScope = 571 std::unique_ptr<DelimitedScope>{}); 572 573 static bool classof(const ScopedPrinter *SP) { 574 return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON; 575 } 576 577 void printNumber(StringRef Label, char Value) override { 578 JOS.attribute(Label, Value); 579 } 580 581 void printNumber(StringRef Label, signed char Value) override { 582 JOS.attribute(Label, Value); 583 } 584 585 void printNumber(StringRef Label, unsigned char Value) override { 586 JOS.attribute(Label, Value); 587 } 588 589 void printNumber(StringRef Label, short Value) override { 590 JOS.attribute(Label, Value); 591 } 592 593 void printNumber(StringRef Label, unsigned short Value) override { 594 JOS.attribute(Label, Value); 595 } 596 597 void printNumber(StringRef Label, int Value) override { 598 JOS.attribute(Label, Value); 599 } 600 601 void printNumber(StringRef Label, unsigned int Value) override { 602 JOS.attribute(Label, Value); 603 } 604 605 void printNumber(StringRef Label, long Value) override { 606 JOS.attribute(Label, Value); 607 } 608 609 void printNumber(StringRef Label, unsigned long Value) override { 610 JOS.attribute(Label, Value); 611 } 612 613 void printNumber(StringRef Label, long long Value) override { 614 JOS.attribute(Label, Value); 615 } 616 617 void printNumber(StringRef Label, unsigned long long Value) override { 618 JOS.attribute(Label, Value); 619 } 620 621 void printNumber(StringRef Label, float Value) override { 622 JOS.attribute(Label, Value); 623 } 624 625 void printNumber(StringRef Label, double Value) override { 626 JOS.attribute(Label, Value); 627 } 628 629 void printNumber(StringRef Label, const APSInt &Value) override { 630 JOS.attributeBegin(Label); 631 printAPSInt(Value); 632 JOS.attributeEnd(); 633 } 634 635 void printBoolean(StringRef Label, bool Value) override { 636 JOS.attribute(Label, Value); 637 } 638 639 void printList(StringRef Label, const ArrayRef<bool> List) override { 640 printListImpl(Label, List); 641 } 642 643 void printList(StringRef Label, const ArrayRef<std::string> List) override { 644 printListImpl(Label, List); 645 } 646 647 void printList(StringRef Label, const ArrayRef<uint64_t> List) override { 648 printListImpl(Label, List); 649 } 650 651 void printList(StringRef Label, const ArrayRef<uint32_t> List) override { 652 printListImpl(Label, List); 653 } 654 655 void printList(StringRef Label, const ArrayRef<uint16_t> List) override { 656 printListImpl(Label, List); 657 } 658 659 void printList(StringRef Label, const ArrayRef<uint8_t> List) override { 660 printListImpl(Label, List); 661 } 662 663 void printList(StringRef Label, const ArrayRef<int64_t> List) override { 664 printListImpl(Label, List); 665 } 666 667 void printList(StringRef Label, const ArrayRef<int32_t> List) override { 668 printListImpl(Label, List); 669 } 670 671 void printList(StringRef Label, const ArrayRef<int16_t> List) override { 672 printListImpl(Label, List); 673 } 674 675 void printList(StringRef Label, const ArrayRef<int8_t> List) override { 676 printListImpl(Label, List); 677 } 678 679 void printList(StringRef Label, const ArrayRef<APSInt> List) override { 680 JOS.attributeArray(Label, [&]() { 681 for (const APSInt &Item : List) { 682 printAPSInt(Item); 683 } 684 }); 685 } 686 687 void printString(StringRef Value) override { JOS.value(Value); } 688 689 void printString(StringRef Label, StringRef Value) override { 690 JOS.attribute(Label, Value); 691 } 692 693 void objectBegin() override { 694 scopedBegin({Scope::Object, ScopeKind::NoAttribute}); 695 } 696 697 void objectBegin(StringRef Label) override { 698 scopedBegin(Label, Scope::Object); 699 } 700 701 void objectEnd() override { scopedEnd(); } 702 703 void arrayBegin() override { 704 scopedBegin({Scope::Array, ScopeKind::NoAttribute}); 705 } 706 707 void arrayBegin(StringRef Label) override { 708 scopedBegin(Label, Scope::Array); 709 } 710 711 void arrayEnd() override { scopedEnd(); } 712 713private: 714 // Output HexNumbers as decimals so that they're easier to parse. 715 uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; } 716 717 void printAPSInt(const APSInt &Value) { 718 JOS.rawValueBegin() << Value; 719 JOS.rawValueEnd(); 720 } 721 722 void printFlagsImpl(StringRef Label, HexNumber Value, 723 ArrayRef<FlagEntry> Flags) override { 724 JOS.attributeObject(Label, [&]() { 725 JOS.attribute("Value", hexNumberToInt(Value)); 726 JOS.attributeArray("Flags", [&]() { 727 for (const FlagEntry &Flag : Flags) { 728 JOS.objectBegin(); 729 JOS.attribute("Name", Flag.Name); 730 JOS.attribute("Value", Flag.Value); 731 JOS.objectEnd(); 732 } 733 }); 734 }); 735 } 736 737 void printFlagsImpl(StringRef Label, HexNumber Value, 738 ArrayRef<HexNumber> Flags) override { 739 JOS.attributeObject(Label, [&]() { 740 JOS.attribute("Value", hexNumberToInt(Value)); 741 JOS.attributeArray("Flags", [&]() { 742 for (const HexNumber &Flag : Flags) { 743 JOS.value(Flag.Value); 744 } 745 }); 746 }); 747 } 748 749 template <typename T> void printListImpl(StringRef Label, const T &List) { 750 JOS.attributeArray(Label, [&]() { 751 for (const auto &Item : List) 752 JOS.value(Item); 753 }); 754 } 755 756 void printHexListImpl(StringRef Label, 757 const ArrayRef<HexNumber> List) override { 758 JOS.attributeArray(Label, [&]() { 759 for (const HexNumber &Item : List) { 760 JOS.value(hexNumberToInt(Item)); 761 } 762 }); 763 } 764 765 void printHexImpl(StringRef Label, HexNumber Value) override { 766 JOS.attribute(Label, hexNumberToInt(Value)); 767 } 768 769 void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override { 770 JOS.attributeObject(Label, [&]() { 771 JOS.attribute("Name", Str); 772 JOS.attribute("Value", hexNumberToInt(Value)); 773 }); 774 } 775 776 void printSymbolOffsetImpl(StringRef Label, StringRef Symbol, 777 HexNumber Value) override { 778 JOS.attributeObject(Label, [&]() { 779 JOS.attribute("SymName", Symbol); 780 JOS.attribute("Offset", hexNumberToInt(Value)); 781 }); 782 } 783 784 void printNumberImpl(StringRef Label, StringRef Str, 785 StringRef Value) override { 786 JOS.attributeObject(Label, [&]() { 787 JOS.attribute("Name", Str); 788 JOS.attributeBegin("Value"); 789 JOS.rawValueBegin() << Value; 790 JOS.rawValueEnd(); 791 JOS.attributeEnd(); 792 }); 793 } 794 795 void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value, 796 bool Block, uint32_t StartOffset = 0) override { 797 JOS.attributeObject(Label, [&]() { 798 if (!Str.empty()) 799 JOS.attribute("Value", Str); 800 JOS.attribute("Offset", StartOffset); 801 JOS.attributeArray("Bytes", [&]() { 802 for (uint8_t Val : Value) 803 JOS.value(Val); 804 }); 805 }); 806 } 807 808 void scopedBegin(ScopeContext ScopeCtx) { 809 if (ScopeCtx.Context == Scope::Object) 810 JOS.objectBegin(); 811 else if (ScopeCtx.Context == Scope::Array) 812 JOS.arrayBegin(); 813 ScopeHistory.push_back(ScopeCtx); 814 } 815 816 void scopedBegin(StringRef Label, Scope Ctx) { 817 ScopeKind Kind = ScopeKind::Attribute; 818 if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) { 819 JOS.objectBegin(); 820 Kind = ScopeKind::NestedAttribute; 821 } 822 JOS.attributeBegin(Label); 823 scopedBegin({Ctx, Kind}); 824 } 825 826 void scopedEnd() { 827 ScopeContext ScopeCtx = ScopeHistory.back(); 828 if (ScopeCtx.Context == Scope::Object) 829 JOS.objectEnd(); 830 else if (ScopeCtx.Context == Scope::Array) 831 JOS.arrayEnd(); 832 if (ScopeCtx.Kind == ScopeKind::Attribute || 833 ScopeCtx.Kind == ScopeKind::NestedAttribute) 834 JOS.attributeEnd(); 835 if (ScopeCtx.Kind == ScopeKind::NestedAttribute) 836 JOS.objectEnd(); 837 ScopeHistory.pop_back(); 838 } 839}; 840 841struct DelimitedScope { 842 DelimitedScope(ScopedPrinter &W) : W(&W) {} 843 DelimitedScope() : W(nullptr) {} 844 virtual ~DelimitedScope() = default; 845 virtual void setPrinter(ScopedPrinter &W) = 0; 846 ScopedPrinter *W; 847}; 848 849struct DictScope : DelimitedScope { 850 explicit DictScope() = default; 851 explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); } 852 853 DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) { 854 W.objectBegin(N); 855 } 856 857 void setPrinter(ScopedPrinter &W) override { 858 this->W = &W; 859 W.objectBegin(); 860 } 861 862 ~DictScope() { 863 if (W) 864 W->objectEnd(); 865 } 866}; 867 868struct ListScope : DelimitedScope { 869 explicit ListScope() = default; 870 explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); } 871 872 ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) { 873 W.arrayBegin(N); 874 } 875 876 void setPrinter(ScopedPrinter &W) override { 877 this->W = &W; 878 W.arrayBegin(); 879 } 880 881 ~ListScope() { 882 if (W) 883 W->arrayEnd(); 884 } 885}; 886 887} // namespace llvm 888 889#endif 890