ScopedPrinter.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- ScopedPrinter.h ----------------------------------------*- C++ -*--===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_SUPPORT_SCOPEDPRINTER_H
  14. #define LLVM_SUPPORT_SCOPEDPRINTER_H
  15. #include "llvm/ADT/APSInt.h"
  16. #include "llvm/ADT/ArrayRef.h"
  17. #include "llvm/ADT/SmallVector.h"
  18. #include "llvm/ADT/StringExtras.h"
  19. #include "llvm/ADT/StringRef.h"
  20. #include "llvm/Support/DataTypes.h"
  21. #include "llvm/Support/Endian.h"
  22. #include "llvm/Support/JSON.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. namespace llvm {
  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. 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. struct FlagEntry {
  60. FlagEntry(StringRef Name, char Value)
  61. : Name(Name), Value(static_cast<unsigned char>(Value)) {}
  62. FlagEntry(StringRef Name, signed char Value)
  63. : Name(Name), Value(static_cast<unsigned char>(Value)) {}
  64. FlagEntry(StringRef Name, signed short Value)
  65. : Name(Name), Value(static_cast<unsigned short>(Value)) {}
  66. FlagEntry(StringRef Name, signed int Value)
  67. : Name(Name), Value(static_cast<unsigned int>(Value)) {}
  68. FlagEntry(StringRef Name, signed long Value)
  69. : Name(Name), Value(static_cast<unsigned long>(Value)) {}
  70. FlagEntry(StringRef Name, signed long long Value)
  71. : Name(Name), Value(static_cast<unsigned long long>(Value)) {}
  72. FlagEntry(StringRef Name, unsigned char Value) : Name(Name), Value(Value) {}
  73. FlagEntry(StringRef Name, unsigned short Value) : Name(Name), Value(Value) {}
  74. FlagEntry(StringRef Name, unsigned int Value) : Name(Name), Value(Value) {}
  75. FlagEntry(StringRef Name, unsigned long Value) : Name(Name), Value(Value) {}
  76. FlagEntry(StringRef Name, unsigned long long Value)
  77. : Name(Name), Value(Value) {}
  78. StringRef Name;
  79. uint64_t Value;
  80. };
  81. raw_ostream &operator<<(raw_ostream &OS, const HexNumber &Value);
  82. template <class T> std::string to_string(const T &Value) {
  83. std::string number;
  84. raw_string_ostream stream(number);
  85. stream << Value;
  86. return stream.str();
  87. }
  88. template <typename T, typename TEnum>
  89. std::string enumToString(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) {
  90. for (const EnumEntry<TEnum> &EnumItem : EnumValues)
  91. if (EnumItem.Value == Value)
  92. return std::string(EnumItem.AltName);
  93. return utohexstr(Value, true);
  94. }
  95. class ScopedPrinter {
  96. public:
  97. enum class ScopedPrinterKind {
  98. Base,
  99. JSON,
  100. };
  101. ScopedPrinter(raw_ostream &OS,
  102. ScopedPrinterKind Kind = ScopedPrinterKind::Base)
  103. : OS(OS), Kind(Kind) {}
  104. ScopedPrinterKind getKind() const { return Kind; }
  105. static bool classof(const ScopedPrinter *SP) {
  106. return SP->getKind() == ScopedPrinterKind::Base;
  107. }
  108. virtual ~ScopedPrinter() = default;
  109. void flush() { OS.flush(); }
  110. void indent(int Levels = 1) { IndentLevel += Levels; }
  111. void unindent(int Levels = 1) {
  112. IndentLevel = IndentLevel > Levels ? IndentLevel - Levels : 0;
  113. }
  114. void resetIndent() { IndentLevel = 0; }
  115. int getIndentLevel() { return IndentLevel; }
  116. void setPrefix(StringRef P) { Prefix = P; }
  117. void printIndent() {
  118. OS << Prefix;
  119. for (int i = 0; i < IndentLevel; ++i)
  120. OS << " ";
  121. }
  122. template <typename T> HexNumber hex(T Value) { return HexNumber(Value); }
  123. template <typename T, typename TEnum>
  124. void printEnum(StringRef Label, T Value,
  125. ArrayRef<EnumEntry<TEnum>> EnumValues) {
  126. StringRef Name;
  127. bool Found = false;
  128. for (const auto &EnumItem : EnumValues) {
  129. if (EnumItem.Value == Value) {
  130. Name = EnumItem.Name;
  131. Found = true;
  132. break;
  133. }
  134. }
  135. if (Found)
  136. printHex(Label, Name, Value);
  137. else
  138. printHex(Label, Value);
  139. }
  140. template <typename T, typename TFlag>
  141. void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag>> Flags,
  142. TFlag EnumMask1 = {}, TFlag EnumMask2 = {},
  143. TFlag EnumMask3 = {}) {
  144. SmallVector<FlagEntry, 10> SetFlags;
  145. for (const auto &Flag : Flags) {
  146. if (Flag.Value == 0)
  147. continue;
  148. TFlag EnumMask{};
  149. if (Flag.Value & EnumMask1)
  150. EnumMask = EnumMask1;
  151. else if (Flag.Value & EnumMask2)
  152. EnumMask = EnumMask2;
  153. else if (Flag.Value & EnumMask3)
  154. EnumMask = EnumMask3;
  155. bool IsEnum = (Flag.Value & EnumMask) != 0;
  156. if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
  157. (IsEnum && (Value & EnumMask) == Flag.Value)) {
  158. SetFlags.emplace_back(Flag.Name, Flag.Value);
  159. }
  160. }
  161. llvm::sort(SetFlags, &flagName);
  162. printFlagsImpl(Label, hex(Value), SetFlags);
  163. }
  164. template <typename T> void printFlags(StringRef Label, T Value) {
  165. SmallVector<HexNumber, 10> SetFlags;
  166. uint64_t Flag = 1;
  167. uint64_t Curr = Value;
  168. while (Curr > 0) {
  169. if (Curr & 1)
  170. SetFlags.emplace_back(Flag);
  171. Curr >>= 1;
  172. Flag <<= 1;
  173. }
  174. printFlagsImpl(Label, hex(Value), SetFlags);
  175. }
  176. virtual void printNumber(StringRef Label, uint64_t Value) {
  177. startLine() << Label << ": " << Value << "\n";
  178. }
  179. virtual void printNumber(StringRef Label, uint32_t Value) {
  180. startLine() << Label << ": " << Value << "\n";
  181. }
  182. virtual void printNumber(StringRef Label, uint16_t Value) {
  183. startLine() << Label << ": " << Value << "\n";
  184. }
  185. virtual void printNumber(StringRef Label, uint8_t Value) {
  186. startLine() << Label << ": " << unsigned(Value) << "\n";
  187. }
  188. virtual void printNumber(StringRef Label, int64_t Value) {
  189. startLine() << Label << ": " << Value << "\n";
  190. }
  191. virtual void printNumber(StringRef Label, int32_t Value) {
  192. startLine() << Label << ": " << Value << "\n";
  193. }
  194. virtual void printNumber(StringRef Label, int16_t Value) {
  195. startLine() << Label << ": " << Value << "\n";
  196. }
  197. virtual void printNumber(StringRef Label, int8_t Value) {
  198. startLine() << Label << ": " << int(Value) << "\n";
  199. }
  200. virtual void printNumber(StringRef Label, const APSInt &Value) {
  201. startLine() << Label << ": " << Value << "\n";
  202. }
  203. template <typename T>
  204. void printNumber(StringRef Label, StringRef Str, T Value) {
  205. printNumberImpl(Label, Str, to_string(Value));
  206. }
  207. virtual void printBoolean(StringRef Label, bool Value) {
  208. startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
  209. }
  210. template <typename... T> void printVersion(StringRef Label, T... Version) {
  211. startLine() << Label << ": ";
  212. printVersionInternal(Version...);
  213. getOStream() << "\n";
  214. }
  215. template <typename T>
  216. void printList(StringRef Label, const ArrayRef<T> List) {
  217. SmallVector<std::string, 10> StringList;
  218. for (const auto &Item : List)
  219. StringList.emplace_back(to_string(Item));
  220. printList(Label, StringList);
  221. }
  222. virtual void printList(StringRef Label, const ArrayRef<bool> List) {
  223. printListImpl(Label, List);
  224. }
  225. virtual void printList(StringRef Label, const ArrayRef<std::string> List) {
  226. printListImpl(Label, List);
  227. }
  228. virtual void printList(StringRef Label, const ArrayRef<uint64_t> List) {
  229. printListImpl(Label, List);
  230. }
  231. virtual void printList(StringRef Label, const ArrayRef<uint32_t> List) {
  232. printListImpl(Label, List);
  233. }
  234. virtual void printList(StringRef Label, const ArrayRef<uint16_t> List) {
  235. printListImpl(Label, List);
  236. }
  237. virtual void printList(StringRef Label, const ArrayRef<uint8_t> List) {
  238. SmallVector<unsigned> NumberList;
  239. for (const uint8_t &Item : List)
  240. NumberList.emplace_back(Item);
  241. printListImpl(Label, NumberList);
  242. }
  243. virtual void printList(StringRef Label, const ArrayRef<int64_t> List) {
  244. printListImpl(Label, List);
  245. }
  246. virtual void printList(StringRef Label, const ArrayRef<int32_t> List) {
  247. printListImpl(Label, List);
  248. }
  249. virtual void printList(StringRef Label, const ArrayRef<int16_t> List) {
  250. printListImpl(Label, List);
  251. }
  252. virtual void printList(StringRef Label, const ArrayRef<int8_t> List) {
  253. SmallVector<int> NumberList;
  254. for (const int8_t &Item : List)
  255. NumberList.emplace_back(Item);
  256. printListImpl(Label, NumberList);
  257. }
  258. virtual void printList(StringRef Label, const ArrayRef<APSInt> List) {
  259. printListImpl(Label, List);
  260. }
  261. template <typename T, typename U>
  262. void printList(StringRef Label, const T &List, const U &Printer) {
  263. startLine() << Label << ": [";
  264. ListSeparator LS;
  265. for (const auto &Item : List) {
  266. OS << LS;
  267. Printer(OS, Item);
  268. }
  269. OS << "]\n";
  270. }
  271. template <typename T> void printHexList(StringRef Label, const T &List) {
  272. SmallVector<HexNumber> HexList;
  273. for (const auto &Item : List)
  274. HexList.emplace_back(Item);
  275. printHexListImpl(Label, HexList);
  276. }
  277. template <typename T> void printHex(StringRef Label, T Value) {
  278. printHexImpl(Label, hex(Value));
  279. }
  280. template <typename T> void printHex(StringRef Label, StringRef Str, T Value) {
  281. printHexImpl(Label, Str, hex(Value));
  282. }
  283. template <typename T>
  284. void printSymbolOffset(StringRef Label, StringRef Symbol, T Value) {
  285. printSymbolOffsetImpl(Label, Symbol, hex(Value));
  286. }
  287. virtual void printString(StringRef Value) { startLine() << Value << "\n"; }
  288. virtual void printString(StringRef Label, StringRef Value) {
  289. startLine() << Label << ": " << Value << "\n";
  290. }
  291. void printStringEscaped(StringRef Label, StringRef Value) {
  292. printStringEscapedImpl(Label, Value);
  293. }
  294. void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
  295. printBinaryImpl(Label, Str, Value, false);
  296. }
  297. void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
  298. auto V =
  299. ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
  300. printBinaryImpl(Label, Str, V, false);
  301. }
  302. void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
  303. printBinaryImpl(Label, StringRef(), Value, false);
  304. }
  305. void printBinary(StringRef Label, ArrayRef<char> Value) {
  306. auto V =
  307. ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
  308. printBinaryImpl(Label, StringRef(), V, false);
  309. }
  310. void printBinary(StringRef Label, StringRef Value) {
  311. auto V =
  312. ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
  313. printBinaryImpl(Label, StringRef(), V, false);
  314. }
  315. void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
  316. uint32_t StartOffset) {
  317. printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
  318. }
  319. void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
  320. printBinaryImpl(Label, StringRef(), Value, true);
  321. }
  322. void printBinaryBlock(StringRef Label, StringRef Value) {
  323. auto V =
  324. ArrayRef(reinterpret_cast<const uint8_t *>(Value.data()), Value.size());
  325. printBinaryImpl(Label, StringRef(), V, true);
  326. }
  327. template <typename T> void printObject(StringRef Label, const T &Value) {
  328. printString(Label, to_string(Value));
  329. }
  330. virtual void objectBegin() { scopedBegin('{'); }
  331. virtual void objectBegin(StringRef Label) { scopedBegin(Label, '{'); }
  332. virtual void objectEnd() { scopedEnd('}'); }
  333. virtual void arrayBegin() { scopedBegin('['); }
  334. virtual void arrayBegin(StringRef Label) { scopedBegin(Label, '['); }
  335. virtual void arrayEnd() { scopedEnd(']'); }
  336. virtual raw_ostream &startLine() {
  337. printIndent();
  338. return OS;
  339. }
  340. virtual raw_ostream &getOStream() { return OS; }
  341. private:
  342. template <typename T> void printVersionInternal(T Value) {
  343. getOStream() << Value;
  344. }
  345. template <typename S, typename T, typename... TArgs>
  346. void printVersionInternal(S Value, T Value2, TArgs... Args) {
  347. getOStream() << Value << ".";
  348. printVersionInternal(Value2, Args...);
  349. }
  350. static bool flagName(const FlagEntry &LHS, const FlagEntry &RHS) {
  351. return LHS.Name < RHS.Name;
  352. }
  353. virtual void printBinaryImpl(StringRef Label, StringRef Str,
  354. ArrayRef<uint8_t> Value, bool Block,
  355. uint32_t StartOffset = 0);
  356. virtual void printFlagsImpl(StringRef Label, HexNumber Value,
  357. ArrayRef<FlagEntry> Flags) {
  358. startLine() << Label << " [ (" << Value << ")\n";
  359. for (const auto &Flag : Flags)
  360. startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
  361. startLine() << "]\n";
  362. }
  363. virtual void printFlagsImpl(StringRef Label, HexNumber Value,
  364. ArrayRef<HexNumber> Flags) {
  365. startLine() << Label << " [ (" << Value << ")\n";
  366. for (const auto &Flag : Flags)
  367. startLine() << " " << Flag << '\n';
  368. startLine() << "]\n";
  369. }
  370. template <typename T> void printListImpl(StringRef Label, const T List) {
  371. startLine() << Label << ": [";
  372. ListSeparator LS;
  373. for (const auto &Item : List)
  374. OS << LS << Item;
  375. OS << "]\n";
  376. }
  377. virtual void printHexListImpl(StringRef Label,
  378. const ArrayRef<HexNumber> List) {
  379. startLine() << Label << ": [";
  380. ListSeparator LS;
  381. for (const auto &Item : List)
  382. OS << LS << hex(Item);
  383. OS << "]\n";
  384. }
  385. virtual void printHexImpl(StringRef Label, HexNumber Value) {
  386. startLine() << Label << ": " << Value << "\n";
  387. }
  388. virtual void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) {
  389. startLine() << Label << ": " << Str << " (" << Value << ")\n";
  390. }
  391. virtual void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
  392. HexNumber Value) {
  393. startLine() << Label << ": " << Symbol << '+' << Value << '\n';
  394. }
  395. virtual void printNumberImpl(StringRef Label, StringRef Str,
  396. StringRef Value) {
  397. startLine() << Label << ": " << Str << " (" << Value << ")\n";
  398. }
  399. virtual void printStringEscapedImpl(StringRef Label, StringRef Value) {
  400. startLine() << Label << ": ";
  401. OS.write_escaped(Value);
  402. OS << '\n';
  403. }
  404. void scopedBegin(char Symbol) {
  405. startLine() << Symbol << '\n';
  406. indent();
  407. }
  408. void scopedBegin(StringRef Label, char Symbol) {
  409. startLine() << Label;
  410. if (!Label.empty())
  411. OS << ' ';
  412. OS << Symbol << '\n';
  413. indent();
  414. }
  415. void scopedEnd(char Symbol) {
  416. unindent();
  417. startLine() << Symbol << '\n';
  418. }
  419. raw_ostream &OS;
  420. int IndentLevel = 0;
  421. StringRef Prefix;
  422. ScopedPrinterKind Kind;
  423. };
  424. template <>
  425. inline void
  426. ScopedPrinter::printHex<support::ulittle16_t>(StringRef Label,
  427. support::ulittle16_t Value) {
  428. startLine() << Label << ": " << hex(Value) << "\n";
  429. }
  430. struct DelimitedScope;
  431. class JSONScopedPrinter : public ScopedPrinter {
  432. private:
  433. enum class Scope {
  434. Array,
  435. Object,
  436. };
  437. enum class ScopeKind {
  438. NoAttribute,
  439. Attribute,
  440. NestedAttribute,
  441. };
  442. struct ScopeContext {
  443. Scope Context;
  444. ScopeKind Kind;
  445. ScopeContext(Scope Context, ScopeKind Kind = ScopeKind::NoAttribute)
  446. : Context(Context), Kind(Kind) {}
  447. };
  448. SmallVector<ScopeContext, 8> ScopeHistory;
  449. json::OStream JOS;
  450. std::unique_ptr<DelimitedScope> OuterScope;
  451. public:
  452. JSONScopedPrinter(raw_ostream &OS, bool PrettyPrint = false,
  453. std::unique_ptr<DelimitedScope> &&OuterScope =
  454. std::unique_ptr<DelimitedScope>{});
  455. static bool classof(const ScopedPrinter *SP) {
  456. return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
  457. }
  458. void printNumber(StringRef Label, uint64_t Value) override {
  459. JOS.attribute(Label, Value);
  460. }
  461. void printNumber(StringRef Label, uint32_t Value) override {
  462. JOS.attribute(Label, Value);
  463. }
  464. void printNumber(StringRef Label, uint16_t Value) override {
  465. JOS.attribute(Label, Value);
  466. }
  467. void printNumber(StringRef Label, uint8_t Value) override {
  468. JOS.attribute(Label, Value);
  469. }
  470. void printNumber(StringRef Label, int64_t Value) override {
  471. JOS.attribute(Label, Value);
  472. }
  473. void printNumber(StringRef Label, int32_t Value) override {
  474. JOS.attribute(Label, Value);
  475. }
  476. void printNumber(StringRef Label, int16_t Value) override {
  477. JOS.attribute(Label, Value);
  478. }
  479. void printNumber(StringRef Label, int8_t Value) override {
  480. JOS.attribute(Label, Value);
  481. }
  482. void printNumber(StringRef Label, const APSInt &Value) override {
  483. JOS.attributeBegin(Label);
  484. printAPSInt(Value);
  485. JOS.attributeEnd();
  486. }
  487. void printBoolean(StringRef Label, bool Value) override {
  488. JOS.attribute(Label, Value);
  489. }
  490. void printList(StringRef Label, const ArrayRef<bool> List) override {
  491. printListImpl(Label, List);
  492. }
  493. void printList(StringRef Label, const ArrayRef<std::string> List) override {
  494. printListImpl(Label, List);
  495. }
  496. void printList(StringRef Label, const ArrayRef<uint64_t> List) override {
  497. printListImpl(Label, List);
  498. }
  499. void printList(StringRef Label, const ArrayRef<uint32_t> List) override {
  500. printListImpl(Label, List);
  501. }
  502. void printList(StringRef Label, const ArrayRef<uint16_t> List) override {
  503. printListImpl(Label, List);
  504. }
  505. void printList(StringRef Label, const ArrayRef<uint8_t> List) override {
  506. printListImpl(Label, List);
  507. }
  508. void printList(StringRef Label, const ArrayRef<int64_t> List) override {
  509. printListImpl(Label, List);
  510. }
  511. void printList(StringRef Label, const ArrayRef<int32_t> List) override {
  512. printListImpl(Label, List);
  513. }
  514. void printList(StringRef Label, const ArrayRef<int16_t> List) override {
  515. printListImpl(Label, List);
  516. }
  517. void printList(StringRef Label, const ArrayRef<int8_t> List) override {
  518. printListImpl(Label, List);
  519. }
  520. void printList(StringRef Label, const ArrayRef<APSInt> List) override {
  521. JOS.attributeArray(Label, [&]() {
  522. for (const APSInt &Item : List) {
  523. printAPSInt(Item);
  524. }
  525. });
  526. }
  527. void printString(StringRef Value) override { JOS.value(Value); }
  528. void printString(StringRef Label, StringRef Value) override {
  529. JOS.attribute(Label, Value);
  530. }
  531. void objectBegin() override {
  532. scopedBegin({Scope::Object, ScopeKind::NoAttribute});
  533. }
  534. void objectBegin(StringRef Label) override {
  535. scopedBegin(Label, Scope::Object);
  536. }
  537. void objectEnd() override { scopedEnd(); }
  538. void arrayBegin() override {
  539. scopedBegin({Scope::Array, ScopeKind::NoAttribute});
  540. }
  541. void arrayBegin(StringRef Label) override {
  542. scopedBegin(Label, Scope::Array);
  543. }
  544. void arrayEnd() override { scopedEnd(); }
  545. private:
  546. // Output HexNumbers as decimals so that they're easier to parse.
  547. uint64_t hexNumberToInt(HexNumber Hex) { return Hex.Value; }
  548. void printAPSInt(const APSInt &Value) {
  549. JOS.rawValueBegin() << Value;
  550. JOS.rawValueEnd();
  551. }
  552. void printFlagsImpl(StringRef Label, HexNumber Value,
  553. ArrayRef<FlagEntry> Flags) override {
  554. JOS.attributeObject(Label, [&]() {
  555. JOS.attribute("RawFlags", hexNumberToInt(Value));
  556. JOS.attributeArray("Flags", [&]() {
  557. for (const FlagEntry &Flag : Flags) {
  558. JOS.objectBegin();
  559. JOS.attribute("Name", Flag.Name);
  560. JOS.attribute("Value", Flag.Value);
  561. JOS.objectEnd();
  562. }
  563. });
  564. });
  565. }
  566. void printFlagsImpl(StringRef Label, HexNumber Value,
  567. ArrayRef<HexNumber> Flags) override {
  568. JOS.attributeObject(Label, [&]() {
  569. JOS.attribute("RawFlags", hexNumberToInt(Value));
  570. JOS.attributeArray("Flags", [&]() {
  571. for (const HexNumber &Flag : Flags) {
  572. JOS.value(Flag.Value);
  573. }
  574. });
  575. });
  576. }
  577. template <typename T> void printListImpl(StringRef Label, const T &List) {
  578. JOS.attributeArray(Label, [&]() {
  579. for (const auto &Item : List)
  580. JOS.value(Item);
  581. });
  582. }
  583. void printHexListImpl(StringRef Label,
  584. const ArrayRef<HexNumber> List) override {
  585. JOS.attributeArray(Label, [&]() {
  586. for (const HexNumber &Item : List) {
  587. JOS.value(hexNumberToInt(Item));
  588. }
  589. });
  590. }
  591. void printHexImpl(StringRef Label, HexNumber Value) override {
  592. JOS.attribute(Label, hexNumberToInt(Value));
  593. }
  594. void printHexImpl(StringRef Label, StringRef Str, HexNumber Value) override {
  595. JOS.attributeObject(Label, [&]() {
  596. JOS.attribute("Value", Str);
  597. JOS.attribute("RawValue", hexNumberToInt(Value));
  598. });
  599. }
  600. void printSymbolOffsetImpl(StringRef Label, StringRef Symbol,
  601. HexNumber Value) override {
  602. JOS.attributeObject(Label, [&]() {
  603. JOS.attribute("SymName", Symbol);
  604. JOS.attribute("Offset", hexNumberToInt(Value));
  605. });
  606. }
  607. void printNumberImpl(StringRef Label, StringRef Str,
  608. StringRef Value) override {
  609. JOS.attributeObject(Label, [&]() {
  610. JOS.attribute("Value", Str);
  611. JOS.attributeBegin("RawValue");
  612. JOS.rawValueBegin() << Value;
  613. JOS.rawValueEnd();
  614. JOS.attributeEnd();
  615. });
  616. }
  617. void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
  618. bool Block, uint32_t StartOffset = 0) override {
  619. JOS.attributeObject(Label, [&]() {
  620. if (!Str.empty())
  621. JOS.attribute("Value", Str);
  622. JOS.attribute("Offset", StartOffset);
  623. JOS.attributeArray("Bytes", [&]() {
  624. for (uint8_t Val : Value)
  625. JOS.value(Val);
  626. });
  627. });
  628. }
  629. void scopedBegin(ScopeContext ScopeCtx) {
  630. if (ScopeCtx.Context == Scope::Object)
  631. JOS.objectBegin();
  632. else if (ScopeCtx.Context == Scope::Array)
  633. JOS.arrayBegin();
  634. ScopeHistory.push_back(ScopeCtx);
  635. }
  636. void scopedBegin(StringRef Label, Scope Ctx) {
  637. ScopeKind Kind = ScopeKind::Attribute;
  638. if (ScopeHistory.empty() || ScopeHistory.back().Context != Scope::Object) {
  639. JOS.objectBegin();
  640. Kind = ScopeKind::NestedAttribute;
  641. }
  642. JOS.attributeBegin(Label);
  643. scopedBegin({Ctx, Kind});
  644. }
  645. void scopedEnd() {
  646. ScopeContext ScopeCtx = ScopeHistory.back();
  647. if (ScopeCtx.Context == Scope::Object)
  648. JOS.objectEnd();
  649. else if (ScopeCtx.Context == Scope::Array)
  650. JOS.arrayEnd();
  651. if (ScopeCtx.Kind == ScopeKind::Attribute ||
  652. ScopeCtx.Kind == ScopeKind::NestedAttribute)
  653. JOS.attributeEnd();
  654. if (ScopeCtx.Kind == ScopeKind::NestedAttribute)
  655. JOS.objectEnd();
  656. ScopeHistory.pop_back();
  657. }
  658. };
  659. struct DelimitedScope {
  660. DelimitedScope(ScopedPrinter &W) : W(&W) {}
  661. DelimitedScope() : W(nullptr) {}
  662. virtual ~DelimitedScope() = default;
  663. virtual void setPrinter(ScopedPrinter &W) = 0;
  664. ScopedPrinter *W;
  665. };
  666. struct DictScope : DelimitedScope {
  667. explicit DictScope() = default;
  668. explicit DictScope(ScopedPrinter &W) : DelimitedScope(W) { W.objectBegin(); }
  669. DictScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
  670. W.objectBegin(N);
  671. }
  672. void setPrinter(ScopedPrinter &W) override {
  673. this->W = &W;
  674. W.objectBegin();
  675. }
  676. ~DictScope() {
  677. if (W)
  678. W->objectEnd();
  679. }
  680. };
  681. struct ListScope : DelimitedScope {
  682. explicit ListScope() = default;
  683. explicit ListScope(ScopedPrinter &W) : DelimitedScope(W) { W.arrayBegin(); }
  684. ListScope(ScopedPrinter &W, StringRef N) : DelimitedScope(W) {
  685. W.arrayBegin(N);
  686. }
  687. void setPrinter(ScopedPrinter &W) override {
  688. this->W = &W;
  689. W.arrayBegin();
  690. }
  691. ~ListScope() {
  692. if (W)
  693. W->arrayEnd();
  694. }
  695. };
  696. } // namespace llvm
  697. #endif
  698. #ifdef __GNUC__
  699. #pragma GCC diagnostic pop
  700. #endif